LyogICAgICAgIERpcmVjdERyYXcgQmFzZSBGdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTctMTk5OSBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyB0aGUgKGludGVybmFsKSBkcml2ZXIgcmVnaXN0cmF0aW9uIGZ1bmN0aW9ucywKICogZHJpdmVyIGVudW1lcmF0aW9uIEFQSXMgYW5kIERpcmVjdERyYXcgY3JlYXRpb24gZnVuY3Rpb25zLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL2V4Y2VwdGlvbi5oIgojaW5jbHVkZSAiZXhjcHQuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCgp0eXBlZGVmIElXaW5lRDNEKiAoV0lOQVBJICpmbldpbmVEaXJlY3QzRENyZWF0ZSkoVUlOVCwgVUlOVCwgSVVua25vd24gKik7CgpzdGF0aWMgSE1PRFVMRSBoV2luZUQzRCA9IChITU9EVUxFKSAtMTsKc3RhdGljIGZuV2luZURpcmVjdDNEQ3JlYXRlIHBXaW5lRGlyZWN0M0RDcmVhdGU7CgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgovKiBUaGUgY29uZmlndXJlZCBkZWZhdWx0IHN1cmZhY2UgKi8KV0lORUQzRFNVUkZUWVBFIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfVU5LTk9XTjsKCi8qIEREcmF3IGxpc3QgYW5kIGNyaXRpY2FsIHNlY3Rpb24gKi8Kc3RhdGljIHN0cnVjdCBsaXN0IGdsb2JhbF9kZHJhd19saXN0ID0gTElTVF9JTklUKGdsb2JhbF9kZHJhd19saXN0KTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2xpc3RfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGRkcmF3X2xpc3RfY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmZGRyYXdfbGlzdF9jcywKICAgIHsgJmRkcmF3X2xpc3RfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgCiAgICAmZGRyYXdfbGlzdF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGRkcmF3X2xpc3RfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2xpc3RfY3MgPSB7ICZkZHJhd19saXN0X2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEhlbHBlciBmdW5jdGlvbiBmb3IgRGlyZWN0RHJhd0NyZWF0ZSBhbmQgZnJpZW5kcwogKiBDcmVhdGVzIGEgbmV3IEREcmF3IGludGVyZmFjZSB3aXRoIHRoZSBnaXZlbiBSRUZJSUQKICoKICogSW50ZXJmYWNlcyB0aGF0IGNhbiBiZSBjcmVhdGVkOgogKiAgSURpcmVjdERyYXcsIElEaXJlY3REcmF3MiwgSURpcmVjdERyYXc0LCBJRGlyZWN0RHJhdzcKICogIElEaXJlY3QzRCwgSURpcmVjdDNEMiwgSURpcmVjdDNEMywgSURpcmVjdDNENy4gKERvZXMgV2luZG93cyByZXR1cm4KICogIElEaXJlY3QzRCBpbnRlcmZhY2VzPykKICoKICogQXJndW1lbnRzOgogKiAgZ3VpZDogSUQgb2YgdGhlIHJlcXVlc3RlZCBkcml2ZXIsIE5VTEwgZm9yIHRoZSBkZWZhdWx0IGRyaXZlci4KICogICAgICAgIFRoZSBHVUlEIGNhbiBiZSBxdWVyaWVkIHdpdGggRGlyZWN0RHJhd0VudW1lcmF0ZShFeClBL1cKICogIEREOiBVc2VkIHRvIHJldHVybiB0aGUgcG9pbnRlciB0byB0aGUgY3JlYXRlZCBvYmplY3QKICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24sIHdoaWNoIGlzIHVuc3VwcG9ydGVkLiBNdXN0IGJlIE5VTEwKICogIGlpZDogcmVxdWVzdGVkIHZlcnNpb24gSUQuCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgSW50ZXJmYWNlIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseQogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyIGlzIG5vdCBOVUxMCiAqICBFX09VVE9GTUVNT1JZIGlmIHNvbWUgYWxsb2NhdGlvbiBmYWlsZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApERFJBV19DcmVhdGUoR1VJRCAqZ3VpZCwKICAgICAgICAgICAgIHZvaWQgKipERCwKICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlciwKICAgICAgICAgICAgIFJFRklJRCBpaWQpCnsKICAgIElEaXJlY3REcmF3SW1wbCAqVGhpcyA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwogICAgSVdpbmVEM0QgKndpbmVEM0QgPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2UgKndpbmVEM0REZXZpY2UgPSBOVUxMOwogICAgSERDIGhEQzsKICAgIFdJTkVEM0RERVZUWVBFIGRldmljZXR5cGU7CgogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQoZ3VpZCksIERELCBVbmtPdXRlcik7CgogICAgKkREID0gTlVMTDsKCiAgICAvKiBXZSBkb24ndCBjYXJlIGFib3V0IHRoaXMgZ3VpZHMuIFdlbGwsIHRoZXJlJ3Mgbm8gc3BlY2lhbCBndWlkIGFueXdheQogICAgICogT0ssIHdlIGNvdWxkCiAgICAgKi8KICAgIGlmIChndWlkID09IChHVUlEICopIEREQ1JFQVRFX0VNVUxBVElPTk9OTFkpCiAgICB7CiAgICAgICAgLyogVXNlIHRoZSByZWZlcmVuY2UgZGV2aWNlIGlkLiBUaGlzIGRvZXNuJ3QgYWN0dWFsbHkgY2hhbmdlIGFueXRoaW5nLAogICAgICAgICAqIFdpbmVEM0QgYWx3YXlzIHVzZXMgT3BlbkdMIGZvciBEM0QgcmVuZGVyaW5nLiBPbmUgY291bGQgbWFrZSBpdCByZXF1ZXN0CiAgICAgICAgICogaW5kaXJlY3QgcmVuZGVyaW5nCiAgICAgICAgICovCiAgICAgICAgZGV2aWNldHlwZSA9IFdJTkVEM0RERVZUWVBFX1JFRjsKICAgIH0KICAgIGVsc2UgaWYoZ3VpZCA9PSAoR1VJRCAqKSBERENSRUFURV9IQVJEV0FSRU9OTFkpCiAgICB7CiAgICAgICAgZGV2aWNldHlwZSA9IFdJTkVEM0RERVZUWVBFX0hBTDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBkZXZpY2V0eXBlID0gMDsKICAgIH0KCiAgICAvKiBERHJhdyBkb2Vzbid0IHN1cHBvcnQgYWdncmVnYXRpb24sIGFjY29yZGluZyB0byBtc2RuICovCiAgICBpZiAoVW5rT3V0ZXIgIT0gTlVMTCkKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOwoKICAgIC8qIERpcmVjdERyYXcgY3JlYXRpb24gY29tZXMgaGVyZSAqLwogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSURpcmVjdERyYXdJbXBsKSk7CiAgICBpZighVGhpcykKICAgIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBjcmVhdGluZyBEaXJlY3REcmF3XG4iKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICAvKiBUaGUgaW50ZXJmYWNlczoKICAgICAqIElEaXJlY3REcmF3IGFuZCBJRGlyZWN0M0QgYXJlIHRoZSBzYW1lIG9iamVjdCwKICAgICAqIFF1ZXJ5SW50ZXJmYWNlIGlzIHVzZWQgdG8gZ2V0IG90aGVyIGludGVyZmFjZXMuCiAgICAgKi8KICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcsICBJRGlyZWN0RHJhdzFfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3MiwgSURpcmVjdERyYXcyX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzMsIElEaXJlY3REcmF3M19WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc0LCBJRGlyZWN0RHJhdzRfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NywgSURpcmVjdERyYXc3X1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QsICBJRGlyZWN0M0QxX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QyLCBJRGlyZWN0M0QyX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QzLCBJRGlyZWN0M0QzX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0Q3LCBJRGlyZWN0M0Q3X1Z0YmwpOwoKICAgIC8qIFNlZSBjb21tZW50cyBpbiBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZSBmb3IgYSBkZXNjcmlwdGlvbgogICAgICogb2YgdGhpcyBtZW1iZXIuCiAgICAgKiBSZWFkIGZyb20gYSByZWdpc3RyeSBrZXksIHNob3VsZCBhZGQgYSB3aW5lY2ZnIG9wdGlvbiBsYXRlcgogICAgICovCiAgICBUaGlzLT5JbXBsVHlwZSA9IERlZmF1bHRTdXJmYWNlVHlwZTsKCiAgICAvKiBHZXQgdGhlIGN1cnJlbnQgc2NyZWVuIHNldHRpbmdzICovCiAgICBoREMgPSBHZXREQygwKTsKICAgIFRoaXMtPm9yaWdfYnBwID0gR2V0RGV2aWNlQ2FwcyhoREMsIEJJVFNQSVhFTCkgKiBHZXREZXZpY2VDYXBzKGhEQywgUExBTkVTKTsKICAgIFJlbGVhc2VEQygwLCBoREMpOwogICAgVGhpcy0+b3JpZ193aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pOwogICAgVGhpcy0+b3JpZ19oZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKTsKCiAgICBpZiAoaFdpbmVEM0QgPT0gKEhNT0RVTEUpIC0xKQogICAgewogICAgICAgIGhXaW5lRDNEID0gTG9hZExpYnJhcnlBKCJ3aW5lZDNkIik7CiAgICAgICAgaWYgKGhXaW5lRDNEKQogICAgICAgICAgICBwV2luZURpcmVjdDNEQ3JlYXRlID0gKGZuV2luZURpcmVjdDNEQ3JlYXRlKSBHZXRQcm9jQWRkcmVzcyhoV2luZUQzRCwgIldpbmVEaXJlY3QzRENyZWF0ZSIpOwogICAgfQoKICAgIGlmICghaFdpbmVEM0QpCiAgICB7CiAgICAgICAgRVJSKCJDb3VsZG4ndCBsb2FkIFdpbmVEM0QgLSBPcGVuR0wgbGlicyBub3QgcHJlc2VudD9cbiIpOwogICAgICAgIGhyID0gRERFUlJfTk9ESVJFQ1REUkFXU1VQUE9SVDsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBXaW5lRDNECiAgICAgKgogICAgICogQWxsIFJlbmRlcmluZyAoMkQgYW5kIDNEKSBpcyByZWxheWVkIHRvIFdpbmVEM0QsCiAgICAgKiBidXQgRGlyZWN0RHJhdyBzcGVjaWZpYyBtYW5hZ2VtZW50LCBsaWtlIEREU1VSRkFDRURFU0MgYW5kIEREUElYRUxGT1JNQVQKICAgICAqIHN0cnVjdHVyZSBoYW5kbGluZyBpcyBoYW5kbGVkIGluIHRoaXMgbGliLgogICAgICovCiAgICB3aW5lRDNEID0gcFdpbmVEaXJlY3QzRENyZWF0ZSgwIC8qIFNES1ZlcnNpb24gKi8sIDcgLyogRFhWZXJzaW9uICovLCAoSVVua25vd24gKikgVGhpcyAvKiBQYXJlbnQgKi8pOwogICAgaWYoIXdpbmVEM0QpCiAgICB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gaW5pdGlhbGlzZSBXaW5lRDNEXG4iKTsKICAgICAgICBociA9IEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQogICAgVGhpcy0+d2luZUQzRCA9IHdpbmVEM0Q7CiAgICBUUkFDRSgiV2luZUQzRCBjcmVhdGVkIGF0ICVwXG4iLCB3aW5lRDNEKTsKCiAgICAvKiBJbml0aWFsaXplZCBtZW1iZXIuLi4KICAgICAqCiAgICAgKiBJdCBpcyBzZXQgdG8gZmFsc2UgYXQgY3JlYXRpb24gdGltZSwgYW5kIHNldCB0byB0cnVlIGluCiAgICAgKiBJRGlyZWN0RHJhdzc6OkluaXRpYWxpemUuIEl0cyBzb2xlIHB1cnBvc2UgaXMgdG8gcmV0dXJuIEREX09LIG9uCiAgICAgKiBpbml0aWFsaXplIG9ubHkgb25jZQogICAgICovCiAgICBUaGlzLT5pbml0aWFsaXplZCA9IEZBTFNFOwoKICAgIC8qIEluaXRpYWxpemUgV2luZUQzRERldmljZQogICAgICoKICAgICAqIEl0IGlzIHVzZWQgZm9yIHNjcmVlbiBzZXR1cCwgc3VyZmFjZSBhbmQgcGFsZXR0ZSBjcmVhdGlvbgogICAgICogV2hlbiBhIERpcmVjdDNERGV2aWNlNyBpcyBjcmVhdGVkLCB0aGUgRDNEIGNhcGFiaWxpdGllcyBvZiBXaW5lRDNEIGFyZQogICAgICogaW5pdGlhbGl6ZWQKICAgICAqLwogICAgaHIgPSBJV2luZUQzRF9DcmVhdGVEZXZpY2Uod2luZUQzRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLypEM0RfQURBUFRFUl9ERUZBVUxUKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2V0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgLyogRm9jdXNXaW5kb3csIGRvbid0IGtub3cgeWV0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBCZWhhdmlvckZsYWdzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgd2luZUQzRERldmljZSwgcmVzdWx0ID0gJXhcbiIsIGhyKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CiAgICBUaGlzLT53aW5lRDNERGV2aWNlID0gd2luZUQzRERldmljZTsKICAgIFRSQUNFKCJ3aW5lRDNERGV2aWNlIGNyZWF0ZWQgYXQgJXBcbiIsIFRoaXMtPndpbmVEM0REZXZpY2UpOwoKICAgIC8qIFJlZ2lzdGVyIHRoZSB3aW5kb3cgY2xhc3MKICAgICAqCiAgICAgKiBJdCBpcyB1c2VkIHRvIGNyZWF0ZSBhIGhpZGRlbiB3aW5kb3cgZm9yIEQzRAogICAgICogcmVuZGVyaW5nLCBpZiB0aGUgYXBwbGljYXRpb24gZGlkbid0IHBhc3Mgb25lLgogICAgICogSXQgY2FuIGFsc28gYmUgdXNlZCBmb3IgQ3JlYXRpbmcgYSBkZXZpY2Ugd2luZG93CiAgICAgKiBmcm9tIFNldENvb3BlcmF0aXZlTGV2ZWwKICAgICAqCiAgICAgKiBUaGUgbmFtZTogRERSQVdfPGFkZHJlc3M+LiBUaGUgY2xhc3NuYW1lIGlzCiAgICAgKiAzMiBiaXQgbG9uZywgc28gYSA2NCBiaXQgYWRkcmVzcyB3aWxsIGZpdCBuaWNlbHkKICAgICAqIChXaWxsIHRoaXMgYmUgY29tcGlsZWQgZm9yIDY0IGJpdCBhbnl3YXk/KQogICAgICoKICAgICAqLwogICAgc3ByaW50ZihUaGlzLT5jbGFzc25hbWUsICJERFJBV18lcCIsIFRoaXMpOwoKICAgIG1lbXNldCgmVGhpcy0+d25kX2NsYXNzLCAwLCBzaXplb2YoVGhpcy0+d25kX2NsYXNzKSk7CiAgICBUaGlzLT53bmRfY2xhc3Muc3R5bGUgPSBDU19IUkVEUkFXIHwgQ1NfVlJFRFJBVzsKICAgIFRoaXMtPnduZF9jbGFzcy5scGZuV25kUHJvYyA9IERlZldpbmRvd1Byb2NBOwogICAgVGhpcy0+d25kX2NsYXNzLmNiQ2xzRXh0cmEgPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmNiV25kRXh0cmEgPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmhJbnN0YW5jZSA9IEdldE1vZHVsZUhhbmRsZUEoMCk7CiAgICBUaGlzLT53bmRfY2xhc3MuaEljb24gPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmhDdXJzb3IgPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmhickJhY2tncm91bmQgPSAoSEJSVVNIKSBHZXRTdG9ja09iamVjdChCTEFDS19CUlVTSCk7CiAgICBUaGlzLT53bmRfY2xhc3MubHBzek1lbnVOYW1lID0gTlVMTDsKICAgIFRoaXMtPnduZF9jbGFzcy5scHN6Q2xhc3NOYW1lID0gVGhpcy0+Y2xhc3NuYW1lOwogICAgaWYoIVJlZ2lzdGVyQ2xhc3NBKCZUaGlzLT53bmRfY2xhc3MpKQogICAgewogICAgICAgIEVSUigiUmVnaXN0ZXJDbGFzc0EgZmFpbGVkIVxuIik7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIC8qIEdldCB0aGUgYW1vdW50IG9mIHZpZGVvIG1lbW9yeSAqLwogICAgVGhpcy0+dG90YWxfdmlkbWVtID0gSVdpbmVEM0REZXZpY2VfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbShUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICAvKiBJbml0aWFsaXplIHRoZSBjYXBzICovCiAgICBUaGlzLT5jYXBzLmR3U2l6ZSA9IHNpemVvZihUaGlzLT5jYXBzKTsKLyogZG8gbm90IHJlcG9ydCBERENBUFNfT1ZFUkxBWSBhbmQgZnJpZW5kcyBzaW5jZSB3ZSBkb24ndCBzdXBwb3J0IG92ZXJsYXlzICovCiNkZWZpbmUgQkxJVF9DQVBTIChERENBUFNfQkxUIHwgRERDQVBTX0JMVENPTE9SRklMTCB8IEREQ0FQU19CTFRERVBUSEZJTEwgXAogICAgICAgICAgfCBERENBUFNfQkxUU1RSRVRDSCB8IEREQ0FQU19DQU5CTFRTWVNNRU0gfCBERENBUFNfQ0FOQ0xJUAkgIFwKICAgICAgICAgIHwgRERDQVBTX0NBTkNMSVBTVFJFVENIRUQgfCBERENBUFNfQ09MT1JLRVkJCQkgIFwKICAgICAgICAgIHwgRERDQVBTX0NPTE9SS0VZSFdBU1NJU1QgfCBERENBUFNfQUxJR05CT1VOREFSWVNSQyApCiNkZWZpbmUgQ0tFWV9DQVBTIChERENLRVlDQVBTX0RFU1RCTFQgfCBERENLRVlDQVBTX1NSQ0JMVCkKI2RlZmluZSBGWF9DQVBTIChEREZYQ0FQU19CTFRBTFBIQSB8IERERlhDQVBTX0JMVE1JUlJPUkxFRlRSSUdIVAlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVE1JUlJPUlVQRE9XTiB8IERERlhDQVBTX0JMVFJPVEFUSU9OOTAJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTSFJJTktYIHwgRERGWENBUFNfQkxUU0hSSU5LWE4JCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUU0hSSU5LWSB8IERERlhDQVBTX0JMVFNIUklOS1hOCQlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNUUkVUQ0hYIHwgRERGWENBUFNfQkxUU1RSRVRDSFhOCQlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNUUkVUQ0hZIHwgRERGWENBUFNfQkxUU1RSRVRDSFlOKQogICAgVGhpcy0+Y2Fwcy5kd0NhcHMgfD0gRERDQVBTX0dESSB8IEREQ0FQU19QQUxFVFRFIHwgQkxJVF9DQVBTOwoKICAgIFRoaXMtPmNhcHMuZHdDYXBzMiB8PSBERENBUFMyX0NFUlRJRklFRCB8IEREQ0FQUzJfTk9QQUdFTE9DS1JFUVVJUkVEIHwKICAgICAgICAgICAgICAgICAgICAgICAgICBERENBUFMyX1BSSU1BUllHQU1NQSB8IEREQ0FQUzJfV0lERVNVUkZBQ0VTIHwKICAgICAgICAgICAgICAgICAgICAgICAgICBERENBUFMyX0NBTlJFTkRFUldJTkRPV0VEOwogICAgVGhpcy0+Y2Fwcy5kd0NLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdQYWxDYXBzIHw9IEREUENBUFNfOEJJVCB8IEREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CiAgICBUaGlzLT5jYXBzLmR3VmlkTWVtVG90YWwgPSBUaGlzLT50b3RhbF92aWRtZW07CiAgICBUaGlzLT5jYXBzLmR3VmlkTWVtRnJlZSA9IFRoaXMtPnRvdGFsX3ZpZG1lbTsKICAgIFRoaXMtPmNhcHMuZHdTVkJDYXBzIHw9IEJMSVRfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTVkJDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1ZCRlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3VlNCQ2FwcyB8PSBCTElUX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3VlNCQ0tleUNhcHMgfD0gQ0tFWV9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkZYQ2FwcyB8PSBGWF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NTQkNhcHMgfD0gQkxJVF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NTQkNLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19BTFBIQSB8IEREU0NBUFNfQkFDS0JVRkZFUiB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfRkxJUCB8IEREU0NBUFNfRlJPTlRCVUZGRVIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX09GRlNDUkVFTlBMQUlOIHwgRERTQ0FQU19QQUxFVFRFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfU1lTVEVNTUVNT1JZIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19WSURFT01FTU9SWSB8IEREU0NBUFNfVklTSUJMRTsKICAgIC8qIEhhY2tzIGZvciBEM0QgY29kZSAqLwogICAgLyogVE9ETzogQ2hlY2sgaWYgV2luZUQzRCBoYXMgM0QgZW5hYmxlZAogICAgICAgTmVlZCBvcGVuZ2wgc3VyZmFjZXMgb3IgYXV0byBmb3IgM0QKICAgICAqLwogICAgaWYoVGhpcy0+SW1wbFR5cGUgPT0gMCB8fCBUaGlzLT5JbXBsVHlwZSA9PSBTVVJGQUNFX09QRU5HTCkKICAgIHsKICAgICAgICBUaGlzLT5jYXBzLmR3Q2FwcyB8PSBERENBUFNfM0Q7CiAgICAgICAgVGhpcy0+Y2Fwcy5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTXzNEREVWSUNFIHwgRERTQ0FQU19NSVBNQVAgfCBERFNDQVBTX1RFWFRVUkUgfCBERFNDQVBTX1pCVUZGRVI7CiAgICB9CiAgICBUaGlzLT5jYXBzLmRkc09sZENhcHMuZHdDYXBzID0gVGhpcy0+Y2Fwcy5kZHNDYXBzLmR3Q2FwczsKCiN1bmRlZiBCTElUX0NBUFMKI3VuZGVmIENLRVlfQ0FQUwojdW5kZWYgRlhfQ0FQUwoKICAgIGxpc3RfaW5pdCgmVGhpcy0+c3VyZmFjZV9saXN0KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfbGlzdF9jcyk7CiAgICBsaXN0X2FkZF9oZWFkKCZnbG9iYWxfZGRyYXdfbGlzdCwgJlRoaXMtPmRkcmF3X2xpc3RfZW50cnkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2xpc3RfY3MpOwoKICAgIC8qIENhbGwgUXVlcnlJbnRlcmZhY2UgdG8gZ2V0IHRoZSBwb2ludGVyIHRvIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLiBUaGlzIGFsc28gaW5pdGlhbGl6ZXMKICAgICAqIFRoZSByZXF1aXJlZCByZWZjb3VudAogICAgICovCiAgICBociA9IElEaXJlY3REcmF3N19RdWVyeUludGVyZmFjZSggSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwgaWlkLCBERCk7CiAgICBpZihTVUNDRUVERUQoaHIpKSByZXR1cm4gRERfT0s7CgplcnJfb3V0OgogICAgLyogTGV0J3MgaG9wZSB3ZSBuZXZlciBuZWVkIHRoaXMgOykgKi8KICAgIGlmKHdpbmVEM0REZXZpY2UpIElXaW5lRDNERGV2aWNlX1JlbGVhc2Uod2luZUQzRERldmljZSk7CiAgICBpZih3aW5lRDNEKSBJV2luZUQzRF9SZWxlYXNlKHdpbmVEM0QpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3Q3JlYXRlIChERFJBVy5AKQogKgogKiBDcmVhdGVzIGxlZ2FjeSBEaXJlY3REcmF3IEludGVyZmFjZXMuIENhbid0IGNyZWF0ZSBJRGlyZWN0RHJhdzcKICogaW50ZXJmYWNlcyBpbiB0aGVvcnkKICoKICogQXJndW1lbnRzLCByZXR1cm4gdmFsdWVzOiBTZWUgRERSQVdfQ3JlYXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0NyZWF0ZShHVUlEICpHVUlELAogICAgICAgICAgICAgICAgIElEaXJlY3REcmF3ICoqREQsCiAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBUUkFDRSgiKCVzLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChHVUlEKSwgREQsIFVua091dGVyKTsKCiAgICByZXR1cm4gRERSQVdfQ3JlYXRlKEdVSUQsICh2b2lkICoqKSBERCwgVW5rT3V0ZXIsICZJSURfSURpcmVjdERyYXcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0NyZWF0ZUV4IChERFJBVy5AKQogKgogKiBPbmx5IGNyZWF0ZXMgbmV3IElEaXJlY3REcmF3NyBpbnRlcmZhY2VzLCBzdXBwb3NlZCB0byBmYWlsIGlmIGxlZ2FjeQogKiBpbnRlcmZhY2VzIGFyZSByZXF1ZXN0ZWQuCiAqCiAqIEFyZ3VtZW50cywgcmV0dXJuIHZhbHVlczogU2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdDcmVhdGVFeChHVUlEICpHVUlELAogICAgICAgICAgICAgICAgICAgdm9pZCAqKkRELAogICAgICAgICAgICAgICAgICAgUkVGSUlEIGlpZCwKICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgVFJBQ0UoIiglcywlcCwlcywlcClcbiIsIGRlYnVnc3RyX2d1aWQoR1VJRCksIERELCBkZWJ1Z3N0cl9ndWlkKGlpZCksIFVua091dGVyKTsKCiAgICBpZiAoIUlzRXF1YWxHVUlEKGlpZCwgJklJRF9JRGlyZWN0RHJhdzcpKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIHJldHVybiBERFJBV19DcmVhdGUoR1VJRCwgREQsIFVua091dGVyLCBpaWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZUEgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgbGVnYWN5IGRkcmF3IGRyaXZlcnMsIGFzY2lpIHZlcnNpb24uIFdlIG9ubHkgaGF2ZSBvbmUKICogZHJpdmVyLCB3aGljaCByZWxheXMgdG8gV2luZUQzRC4gSWYgd2Ugd2VyZSBzdWZmaWNpZW50bHkgY29vbCwKICogd2UgY291bGQgb2ZmZXIgdmFyaW91cyBpbnRlcmZhY2VzLCB3aGljaCB1c2UgYSBkaWZmZXJlbnQgZGVmYXVsdCBzdXJmYWNlCiAqIGltcGxlbWVudGF0aW9uLCBidXQgSSB0aGluayBpdCdzIGJldHRlciB0byBvZmZlciB0aGlzIGNob2ljZSBpbgogKiB3aW5lY2ZnLCBiZWNhdXNlIHNvbWUgYXBwcyB1c2UgdGhlIGRlZmF1bHQgZHJpdmVyLCBzbyB3ZSB3b3VsZCBuZWVkCiAqIGEgd2luZWNmZyBvcHRpb24gYW55d2F5LCBhbmQgdGhlcmUgc2hvdWxkbid0IGJlIDIgd2F5cyB0byBzZXQgb25lIHNldHRpbmcKICoKICogQXJndW1lbnRzOgogKiAgQ2FsbGJhY2s6IENhbGxiYWNrIGZ1bmN0aW9uIGZyb20gdGhlIGFwcAogKiAgQ29udGV4dDogQXJndW1lbnQgdG8gdGhlIGNhbGwgYmFjay4KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIEVfSU5WQUxJREFSRyBpZiB0aGUgQ2FsbGJhY2sgY2F1c2VkIGEgcGFnZSBmYXVsdAogKgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdFbnVtZXJhdGVBKExQRERFTlVNQ0FMTEJBQ0tBIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0KQp7CiAgICBCT09MIHN0b3AgPSBGQUxTRTsKCiAgICBUUkFDRSgiIEVudW1lcmF0aW5nIGRlZmF1bHQgRGlyZWN0RHJhdyBIQUwgaW50ZXJmYWNlXG4iKTsKICAgIC8qIFdlIG9ubHkgaGF2ZSBvbmUgZHJpdmVyICovCiAgICBfX1RSWQogICAgewogICAgICAgIHN0YXRpYyBDSEFSIGRyaXZlcl9kZXNjW10gPSAiRGlyZWN0RHJhdyBIQUwiLAogICAgICAgIGRyaXZlcl9uYW1lW10gPSAiZGlzcGxheSI7CgogICAgICAgIHN0b3AgPSAhQ2FsbGJhY2soTlVMTCwgZHJpdmVyX2Rlc2MsIGRyaXZlcl9uYW1lLCBDb250ZXh0KTsKICAgIH0KICAgIF9fRVhDRVBUX1BBR0VfRkFVTFQKICAgIHsKICAgICAgICByZXR1cm4gRV9JTlZBTElEQVJHOwogICAgfQogICAgX19FTkRUUlkKCiAgICBUUkFDRSgiIEVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlRXhBIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIERpcmVjdERyYXc3IGRyaXZlcnMsIGFzY2lpIHZlcnNpb24uIFNlZQogKiB0aGUgY29tbWVudHMgYWJvdmUgRGlyZWN0RHJhd0VudW1lcmF0ZUEgZm9yIG1vcmUgZGV0YWlscy4KICoKICogVGhlIEZsYWcgbWVtYmVyIGlzIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdFbnVtZXJhdGVFeEEoTFBEREVOVU1DQUxMQkFDS0VYQSBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBCT09MIHN0b3AgPSBGQUxTRTsKICAgIFRSQUNFKCJFbnVtZXJhdGluZyBkZWZhdWx0IERpcmVjdERyYXcgSEFMIGludGVyZmFjZVxuIik7CgogICAgLyogV2Ugb25seSBoYXZlIG9uZSBkcml2ZXIgYnkgbm93ICovCiAgICBfX1RSWQogICAgewogICAgICAgIHN0YXRpYyBDSEFSIGRyaXZlcl9kZXNjW10gPSAiRGlyZWN0RHJhdyBIQUwiLAogICAgICAgIGRyaXZlcl9uYW1lW10gPSAiZGlzcGxheSI7CgogICAgICAgIC8qIFF1aWNrVGltZSBleHBlY3RzIHRoZSBkZXNjcmlwdGlvbiAiRGlyZWN0RHJhdyBIQUwiICovCiAgICAgICAgc3RvcCA9ICFDYWxsYmFjayhOVUxMLCBkcml2ZXJfZGVzYywgZHJpdmVyX25hbWUsIENvbnRleHQsIDApOwogICAgfQogICAgX19FWENFUFRfUEFHRV9GQVVMVAogICAgewogICAgICAgIHJldHVybiBFX0lOVkFMSURBUkc7CiAgICB9CiAgICBfX0VORFRSWTsKCiAgICBUUkFDRSgiRW5kIG9mIGVudW1lcmF0aW9uXG4iKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdFbnVtZXJhdGVXIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIGxlZ2FjeSBkcml2ZXJzLCB1bmljb2RlIHZlcnNpb24uIFNlZQogKiB0aGUgY29tbWVudHMgYWJvdmUgRGlyZWN0RHJhd0VudW1lcmF0ZUEgZm9yIG1vcmUgZGV0YWlscy4KICoKICogVGhlIEZsYWcgbWVtYmVyIGlzIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZUV4VyAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBEaXJlY3REcmF3NyBkcml2ZXJzLCB1bmljb2RlIHZlcnNpb24uIFNlZQogKiB0aGUgY29tbWVudHMgYWJvdmUgRGlyZWN0RHJhd0VudW1lcmF0ZUEgZm9yIG1vcmUgZGV0YWlscy4KICoKICogVGhlIEZsYWcgbWVtYmVyIGlzIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ2xhc3NmYWN0b3J5IGltcGxlbWVudGF0aW9uLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ0ZfQ3JlYXRlRGlyZWN0RHJhdwogKgogKiBERHJhdyBjcmVhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUGFyYW1zOgogKiAgVW5rT3V0ZXI6IFNldCB0byBOVUxMCiAqICBpaWQ6IElEIG9mIHRoZSB3YW50ZWQgaW50ZXJmYWNlCiAqICBvYmo6IEFkZHJlc3MgdG8gcGFzcyB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYmFjawogKgogKiBSZXR1cm5zCiAqICBERF9PSyAvIERERVJSKiwgc2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCkNGX0NyZWF0ZURpcmVjdERyYXcoSVVua25vd24qIFVua091dGVyLCBSRUZJSUQgaWlkLAogICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFVua091dGVyLCBkZWJ1Z3N0cl9ndWlkKGlpZCksIG9iaik7CgogICAgaHIgPSBERFJBV19DcmVhdGUoTlVMTCwgb2JqLCBVbmtPdXRlciwgaWlkKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENGX0NyZWF0ZURpcmVjdERyYXcKICoKICogQ2xpcHBlciBjcmVhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUGFyYW1zOgogKiAgVW5rT3V0ZXI6IFNldCB0byBOVUxMCiAqICBpaWQ6IElEIG9mIHRoZSB3YW50ZWQgaW50ZXJmYWNlCiAqICBvYmo6IEFkZHJlc3MgdG8gcGFzcyB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYmFjawogKgogKiBSZXR1cm5zCiAqICBERF9PSyAvIERERVJSKiwgc2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCkNGX0NyZWF0ZURpcmVjdERyYXdDbGlwcGVyKElVbmtub3duKiBVbmtPdXRlciwgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIEhSRVNVTFQgaHI7CiAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKkNsaXA7CgogICAgaHIgPSBEaXJlY3REcmF3Q3JlYXRlQ2xpcHBlcigwLCAmQ2xpcCwgVW5rT3V0ZXIpOwogICAgaWYgKGhyICE9IEREX09LKSByZXR1cm4gaHI7CgogICAgaHIgPSBJRGlyZWN0RHJhd0NsaXBwZXJfUXVlcnlJbnRlcmZhY2UoQ2xpcCwgcmlpZCwgb2JqKTsKICAgIElEaXJlY3REcmF3Q2xpcHBlcl9SZWxlYXNlKENsaXApOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IG9iamVjdF9jcmVhdGlvbl9pbmZvIG9iamVjdF9jcmVhdGlvbltdID0KewogICAgeyAmQ0xTSURfRGlyZWN0RHJhdywgICAgICAgIENGX0NyZWF0ZURpcmVjdERyYXcgfSwKICAgIHsgJkNMU0lEX0RpcmVjdERyYXc3LCAgICAgICBDRl9DcmVhdGVEaXJlY3REcmF3IH0sCiAgICB7ICZDTFNJRF9EaXJlY3REcmF3Q2xpcHBlciwgQ0ZfQ3JlYXRlRGlyZWN0RHJhd0NsaXBwZXIgfQp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJ5SW50ZXJmYWNlIGZvciB0aGUgY2xhc3MgZmFjdG9yeQogKgogKiBQQVJBTVMKICogICAgcmlpZCAgIFJlZmVyZW5jZSB0byBpZGVudGlmaWVyIG9mIHF1ZXJpZWQgaW50ZXJmYWNlCiAqICAgIHBwdiAgICBBZGRyZXNzIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IEVfTk9JTlRFUkZBQ0UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUXVlcnlJbnRlcmZhY2UoSUNsYXNzRmFjdG9yeSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgb2JqKTsKCiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lDbGFzc0ZhY3RvcnkpKQogICAgewogICAgICAgIElDbGFzc0ZhY3RvcnlfQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KCiAgICBXQVJOKCIoJXApLT4oJXMsJXApLG5vdCBmb3VuZFxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6QWRkUmVmCiAqCiAqIEFkZFJlZiBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUkVUVVJOUwogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQWRkUmVmKElDbGFzc0ZhY3RvcnkgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCktPigpIGluY3JlbWVudGluZyBmcm9tICVkLlxuIiwgVGhpcywgcmVmIC0gMSk7CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OlJlbGVhc2UKICoKICogUmVsZWFzZSBmb3IgdGhlIGNsYXNzIGZhY3RvcnkuIElmIHRoZSByZWZjb3VudCBmYWxscyB0byAwLCB0aGUgb2JqZWN0CiAqIGlzIGRlc3Ryb3llZAogKgogKiBSRVRVUk5TCiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9SZWxlYXNlKElDbGFzc0ZhY3RvcnkgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CiAgICBUUkFDRSgiKCVwKS0+KCkgZGVjcmVtZW50aW5nIGZyb20gJWQuXG4iLCBUaGlzLCByZWYrMSk7CgogICAgaWYgKHJlZiA9PSAwKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwoKICAgIHJldHVybiByZWY7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6Q3JlYXRlSW5zdGFuY2UKICoKICogV2hhdCBpcyB0aGlzPyBTZWVtcyB0byBjcmVhdGUgRGlyZWN0RHJhdyBvYmplY3RzLi4uCiAqCiAqIFBhcmFtcwogKiAgVGhlIHVzdXNhbCB0aGluZ3M/Pz8KICoKICogUkVUVVJOUwogKiAgPz8/CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0NyZWF0ZUluc3RhbmNlKElDbGFzc0ZhY3RvcnkgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXMsJXApXG4iLFRoaXMsVW5rT3V0ZXIsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwoKICAgIHJldHVybiBUaGlzLT5wZm5DcmVhdGVJbnN0YW5jZShVbmtPdXRlciwgcmlpZCwgb2JqKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OkxvY2tTZXJ2ZXIKICoKICogV2hhdCBpcyB0aGlzPwogKgogKiBQYXJhbXMKICogID8/PwogKgogKiBSRVRVUk5TCiAqICBTX09LLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0xvY2tTZXJ2ZXIoSUNsYXNzRmFjdG9yeSAqaWZhY2UsQk9PTCBkb2xvY2spCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVkKSxzdHViIVxuIixUaGlzLGRvbG9jayk7CiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIGNsYXNzIGZhY3RvcnkgVlRhYmxlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwgSUNsYXNzRmFjdG9yeV9WdGJsID0KewogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0FkZFJlZiwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9SZWxlYXNlLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0NyZWF0ZUluc3RhbmNlLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0xvY2tTZXJ2ZXIKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERsbEdldENsYXNzT2JqZWN0IFtERFJBVy5AXQogKiBSZXRyaWV2ZXMgY2xhc3Mgb2JqZWN0IGZyb20gYSBETEwgb2JqZWN0CiAqCiAqIE5PVEVTCiAqICAgIERvY3Mgc2F5IHJldHVybnMgU1REQVBJCiAqCiAqIFBBUkFNUwogKiAgICByY2xzaWQgW0ldIENMU0lEIGZvciB0aGUgY2xhc3Mgb2JqZWN0CiAqICAgIHJpaWQgICBbSV0gUmVmZXJlbmNlIHRvIGlkZW50aWZpZXIgb2YgaW50ZXJmYWNlIGZvciBjbGFzcyBvYmplY3QKICogICAgcHB2ICAgIFtPXSBBZGRyZXNzIG9mIHZhcmlhYmxlIHRvIHJlY2VpdmUgaW50ZXJmYWNlIHBvaW50ZXIgZm9yIHJpaWQKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEUsIEVfT1VUT0ZNRU1PUlksIEVfSU5WQUxJREFSRywKICogICAgICAgICAgICAgRV9VTkVYUEVDVEVECiAqLwpIUkVTVUxUIFdJTkFQSSBEbGxHZXRDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogICAgdW5zaWduZWQgaW50IGk7CiAgICBJQ2xhc3NGYWN0b3J5SW1wbCAqZmFjdG9yeTsKCiAgICBUUkFDRSgiKCVzLCVzLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwoKICAgIGlmICggIUlzRXF1YWxHVUlEKCAmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQgKQoJICYmICEgSXNFcXVhbEdVSUQoICZJSURfSVVua25vd24sIHJpaWQpICkKCXJldHVybiBFX05PSU5URVJGQUNFOwoKICAgIGZvciAoaT0wOyBpIDwgc2l6ZW9mKG9iamVjdF9jcmVhdGlvbikvc2l6ZW9mKG9iamVjdF9jcmVhdGlvblswXSk7IGkrKykKICAgIHsKCWlmIChJc0VxdWFsR1VJRChvYmplY3RfY3JlYXRpb25baV0uY2xzaWQsIHJjbHNpZCkpCgkgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGkgPT0gc2l6ZW9mKG9iamVjdF9jcmVhdGlvbikvc2l6ZW9mKG9iamVjdF9jcmVhdGlvblswXSkpCiAgICB7CglGSVhNRSgiJXM6IG5vIGNsYXNzIGZvdW5kLlxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKCXJldHVybiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwogICAgfQoKICAgIGZhY3RvcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpmYWN0b3J5KSk7CiAgICBpZiAoZmFjdG9yeSA9PSBOVUxMKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKGZhY3RvcnksIElDbGFzc0ZhY3RvcnksIElDbGFzc0ZhY3RvcnlfVnRibCk7CiAgICBmYWN0b3J5LT5yZWYgPSAxOwoKICAgIGZhY3RvcnktPnBmbkNyZWF0ZUluc3RhbmNlID0gb2JqZWN0X2NyZWF0aW9uW2ldLnBmbkNyZWF0ZUluc3RhbmNlOwoKICAgICpwcHYgPSBJQ09NX0lOVEVSRkFDRShmYWN0b3J5LCBJQ2xhc3NGYWN0b3J5KTsKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsQ2FuVW5sb2FkTm93IFtERFJBVy5AXSAgRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBETEwgaXMgaW4gdXNlLgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogU19GQUxTRQogKi8KSFJFU1VMVCBXSU5BUEkgRGxsQ2FuVW5sb2FkTm93KHZvaWQpCnsKICAgIEZJWE1FKCIodm9pZCk6IHN0dWJcbiIpOwogICAgcmV0dXJuIFNfRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlc3Ryb3lDYWxsYmFjawogKgogKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgdGhlIEVudW1TdXJmYWNlcyBjYWxsIGluIERsbE1haW4uCiAqIER1bXBzIHNvbWUgc3VyZmFjZSBpbmZvIGFuZCByZWxlYXNlcyB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBzdXJmOiBUaGUgZW51bWVyYXRlZCBzdXJmYWNlCiAqICBkZXNjOiBpdCdzIGRlc2NyaXB0aW9uCiAqICBjb250ZXh0OiBQb2ludGVyIHRvIHRoZSBkZHJhdyBpbXBsCiAqCiAqIFJldHVybnM6CiAqICBEREVOVU1SRVRfT0s7CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRGVzdHJveUNhbGxiYWNrKElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmYsCiAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqZGVzYywKICAgICAgICAgICAgICAgIHZvaWQgKmNvbnRleHQpCnsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKkltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBzdXJmKTsKICAgIElEaXJlY3REcmF3SW1wbCAqZGRyYXcgPSAoSURpcmVjdERyYXdJbXBsICopIGNvbnRleHQ7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmYpOyAgLyogRm9yIHRoZSBFbnVtU3VyZmFjZXMgKi8KICAgIFdBUk4oIlN1cmZhY2UgJXAgaGFzIGFuIHJlZmVyZW5jZSBjb3VudCBvZiAlZFxuIiwgSW1wbCwgcmVmKTsKCiAgICAvKiBTa2lwIHN1cmZhY2VzIHdoaWNoIGFyZSBhdHRhY2hlZCBzb21ld2hlcmUgb3Igd2hpY2ggYXJlCiAgICAgKiBwYXJ0IG9mIGEgY29tcGxleCBjb21wb3VuZC4gVGhleSB3aWxsIGdldCByZWxlYXNlZCB3aGVuIGRlc3Ryb3lpbmcKICAgICAqIHRoZSByb290CiAgICAgKi8KICAgIGlmKCAoSW1wbC0+Zmlyc3RfY29tcGxleCAhPSBJbXBsKSB8fCAoSW1wbC0+Zmlyc3RfYXR0YWNoZWQgIT0gSW1wbCkgKQogICAgICAgIHJldHVybiBEREVOVU1SRVRfT0s7CiAgICAvKiBTa2lwIG91ciBkZXB0aCBzdGVuY2lsIHN1cmZhY2UsIGl0IHdpbGwgYmUgcmVsZWFzZWQgd2l0aCB0aGUgcmVuZGVyIHRhcmdldCAqLwogICAgaWYoIEltcGwgPT0gZGRyYXctPkRlcHRoU3RlbmNpbEJ1ZmZlcikKICAgICAgICByZXR1cm4gRERFTlVNUkVUX09LOwoKICAgIC8qIERlc3Ryb3kgdGhlIHN1cmZhY2UgKi8KICAgIHdoaWxlKHJlZikgcmVmID0gSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmYpOwoKICAgIHJldHVybiBEREVOVU1SRVRfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfY29uZmlnX2tleQogKgogKiBSZWFkcyBhIGNvbmZpZyBrZXkgZnJvbSB0aGUgcmVnaXN0cnkuIFRha2VuIGZyb20gV2luZUQzRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmlubGluZSBzdGF0aWMgRFdPUkQgZ2V0X2NvbmZpZ19rZXkoSEtFWSBkZWZrZXksIEhLRVkgYXBwa2V5LCBjb25zdCBjaGFyKiBuYW1lLCBjaGFyKiBidWZmZXIsIERXT1JEIHNpemUpCnsKICAgIGlmICgwICE9IGFwcGtleSAmJiAhUmVnUXVlcnlWYWx1ZUV4QSggYXBwa2V5LCBuYW1lLCAwLCBOVUxMLCAoTFBCWVRFKSBidWZmZXIsICZzaXplICkpIHJldHVybiAwOwogICAgaWYgKDAgIT0gZGVma2V5ICYmICFSZWdRdWVyeVZhbHVlRXhBKCBkZWZrZXksIG5hbWUsIDAsIE5VTEwsIChMUEJZVEUpIGJ1ZmZlciwgJnNpemUgKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxNYWluIChERFJBVy4wKQogKgogKiBDb3VsZCBiZSB1c2VkIHRvIHJlZ2lzdGVyIERpcmVjdERyYXcgZHJpdmVycywgaWYgd2UgaGF2ZSBtb3JlIHRoYW4KICogb25lLiBBbHNvIHVzZWQgdG8gZGVzdHJveSBhbnkgb2JqZWN0cyBsZWZ0IGF0IHVubG9hZCBpZiB0aGUKICogYXBwIGRpZG4ndCByZWxlYXNlIHRoZW0gcHJvcGVybHkoR290aGljIDIsIERpYWJsbyAyLCBNb3RvIHJhY2VyLCAuLi4pCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KQk9PTCBXSU5BUEkKRGxsTWFpbihISU5TVEFOQ0UgaEluc3RETEwsCiAgICAgICAgRFdPUkQgUmVhc29uLAogICAgICAgIHZvaWQgKmxwdikKewogICAgVFJBQ0UoIiglcCwleCwlcClcbiIsIGhJbnN0RExMLCBSZWFzb24sIGxwdik7CiAgICBpZiAoUmVhc29uID09IERMTF9QUk9DRVNTX0FUVEFDSCkKICAgIHsKICAgICAgICBjaGFyIGJ1ZmZlcltNQVhfUEFUSCsxMF07CiAgICAgICAgRFdPUkQgc2l6ZSA9IHNpemVvZihidWZmZXIpOwogICAgICAgIEhLRVkgaGtleSA9IDA7CiAgICAgICAgSEtFWSBhcHBrZXkgPSAwOwogICAgICAgIERXT1JEIGxlbjsKCiAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXERpcmVjdDNEICovCiAgICAgICBpZiAoIFJlZ09wZW5LZXlBKCBIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxXaW5lXFxEaXJlY3QzRCIsICZoa2V5ICkgKSBoa2V5ID0gMDsKCiAgICAgICBsZW4gPSBHZXRNb2R1bGVGaWxlTmFtZUEoIDAsIGJ1ZmZlciwgTUFYX1BBVEggKTsKICAgICAgIGlmIChsZW4gJiYgbGVuIDwgTUFYX1BBVEgpCiAgICAgICB7CiAgICAgICAgICAgIEhLRVkgdG1wa2V5OwogICAgICAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXEFwcERlZmF1bHRzXGFwcC5leGVcRGlyZWN0M0QgKi8KICAgICAgICAgICAgaWYgKCFSZWdPcGVuS2V5QSggSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcV2luZVxcQXBwRGVmYXVsdHMiLCAmdG1wa2V5ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnAsICphcHBuYW1lID0gYnVmZmVyOwogICAgICAgICAgICAgICAgaWYgKChwID0gc3RycmNociggYXBwbmFtZSwgJy8nICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBpZiAoKHAgPSBzdHJyY2hyKCBhcHBuYW1lLCAnXFwnICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBzdHJjYXQoIGFwcG5hbWUsICJcXERpcmVjdDNEIiApOwogICAgICAgICAgICAgICAgVFJBQ0UoImFwcG5hbWUgPSBbJXNdXG4iLCBhcHBuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChSZWdPcGVuS2V5QSggdG1wa2V5LCBhcHBuYW1lLCAmYXBwa2V5ICkpIGFwcGtleSA9IDA7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleSggdG1wa2V5ICk7CiAgICAgICAgICAgIH0KICAgICAgIH0KCiAgICAgICBpZiAoIDAgIT0gaGtleSB8fCAwICE9IGFwcGtleSApCiAgICAgICB7CiAgICAgICAgICAgIGlmICggIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJEaXJlY3REcmF3UmVuZGVyZXIiLCBidWZmZXIsIHNpemUpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoYnVmZmVyLCJnZGkiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGVmYXVsdGluZyB0byBHREkgc3VyZmFjZXNcbiIpOwogICAgICAgICAgICAgICAgICAgIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfR0RJOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChidWZmZXIsIm9wZW5nbCIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEZWZhdWx0aW5nIHRvIG9wZW5nbCBzdXJmYWNlc1xuIik7CiAgICAgICAgICAgICAgICAgICAgRGVmYXVsdFN1cmZhY2VUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIGRlZmF1bHQgc3VyZmFjZSB0eXBlLiBTdXBwb3J0ZWQgYXJlOlxuIGdkaSwgb3BlbmdsXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhoSW5zdERMTCk7CiAgICB9CiAgICBlbHNlIGlmIChSZWFzb24gPT0gRExMX1BST0NFU1NfREVUQUNIKQogICAgewogICAgICAgIGlmKCFsaXN0X2VtcHR5KCZnbG9iYWxfZGRyYXdfbGlzdCkpCiAgICAgICAgewogICAgICAgICAgICBzdHJ1Y3QgbGlzdCAqZW50cnksICplbnRyeTI7CiAgICAgICAgICAgIFdBUk4oIlRoZXJlIGFyZSBzdGlsbCBleGlzdGluZyBEaXJlY3REcmF3IGludGVyZmFjZXMuIFdpbmUgYnVnIG9yIGJ1Z2d5IGFwcGxpY2F0aW9uP1xuIik7CgogICAgICAgICAgICAvKiBXZSByZW1vdmUgZWxlbWV0cyBmcm9tIHRoaXMgbG9vcCAqLwogICAgICAgICAgICBMSVNUX0ZPUl9FQUNIX1NBRkUoZW50cnksIGVudHJ5MiwgJmdsb2JhbF9kZHJhd19saXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgZGVzYzsKICAgICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsICpkZHJhdyA9IExJU1RfRU5UUlkoZW50cnksIElEaXJlY3REcmF3SW1wbCwgZGRyYXdfbGlzdF9lbnRyeSk7CgogICAgICAgICAgICAgICAgV0FSTigiRERyYXcgJXAgaGFzIGEgcmVmY291bnQgb2YgJWRcbiIsIGRkcmF3LCBkZHJhdy0+cmVmNyArIGRkcmF3LT5yZWY0ICsgZGRyYXctPnJlZjMgKyBkZHJhdy0+cmVmMiArIGRkcmF3LT5yZWYxKTsKCiAgICAgICAgICAgICAgICAvKiBBZGQgcmVmZXJlbmNlcyB0byBlYWNoIGludGVyZmFjZSB0byBhdm9pZCBmcmVlaW5nIHRoZW0gdW5leHBlY3RhZGVseSAqLwogICAgICAgICAgICAgICAgSURpcmVjdERyYXdfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdykpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXcyX0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcyKSk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdzNfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzMpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3NF9BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NCkpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXc3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc3KSk7CgogICAgICAgICAgICAgICAgLyogRG9lcyBhIEQzRCBkZXZpY2UgZXhpc3Q/IERlc3Ryb3kgaXQKICAgICAgICAgICAgICAgICAgICAqIFRPRE86IERlc3Ryb3kgYWxsIFZlcnRleCBidWZmZXJzLCBMaWdodHMsIE1hdGVyaWFscwogICAgICAgICAgICAgICAgICAgICogYW5kIGV4ZWN0dXJlIGJ1ZmZlcnMgdG9vCiAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmKGRkcmF3LT5kM2RkZXZpY2UpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiRERyYXcgJXAgaGFzIGQzZGRldmljZSAlcCBhdHRhY2hlZFxuIiwgZGRyYXcsIGRkcmF3LT5kM2RkZXZpY2UpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3QzRERldmljZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdy0+ZDNkZGV2aWNlLCBJRGlyZWN0M0REZXZpY2U3KSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIFRyeSB0byByZWxlYXNlIHRoZSBvYmplY3RzCiAgICAgICAgICAgICAgICAgICAgKiBEbyBhbiBFbnVtU3VyZmFjZXMgdG8gZmluZCBhbnkgaGFuZ2luZyBzdXJmYWNlcwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBtZW1zZXQoJmRlc2MsIDAsIHNpemVvZihkZXNjKSk7CiAgICAgICAgICAgICAgICBkZXNjLmR3U2l6ZSA9IHNpemVvZihkZXNjKTsKICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaSA8PSAxOyBpKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaHIgPSBJRGlyZWN0RHJhdzdfRW51bVN1cmZhY2VzKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERFTlVNU1VSRkFDRVNfQUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBkZHJhdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3Ryb3lDYWxsYmFjayk7CiAgICAgICAgICAgICAgICAgICAgaWYoaHIgIT0gRDNEX09LKQogICAgICAgICAgICAgICAgICAgICAgICBFUlIoIiglcCkgRW51bVN1cmZhY2VzIGZhaWxlZCwgcHJlcGFyZSBmb3IgdHJvdWJsZVxuIiwgZGRyYXcpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIENoZWNrIHRoZSBzdXJmYWNlIGNvdW50ICovCiAgICAgICAgICAgICAgICBpZihkZHJhdy0+c3VyZmFjZXMgPiAwKQogICAgICAgICAgICAgICAgICAgIEVSUigiRERyYXcgJXAgc3RpbGwgaGFzICVkIHN1cmZhY2VzIGF0dGFjaGVkXG4iLCBkZHJhdywgZGRyYXctPnN1cmZhY2VzKTsKCiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIGFsbCBoYW5naW5nIHJlZmVyZW5jZXMgdG8gZGVzdHJveSB0aGUgb2JqZWN0cy4gVGhpcwogICAgICAgICAgICAgICAgICAgICogcmVzdG9yZXMgdGhlIHNjcmVlbiBtb2RlIHRvbwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhd19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdykpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3Ml9SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzIpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzNfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXczKSkpOwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXc0X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NCkpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3N19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzcpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCnZvaWQKcmVtb3ZlX2RkcmF3X29iamVjdChJRGlyZWN0RHJhd0ltcGwgKmRkcmF3KQp7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfbGlzdF9jcyk7CiAgICBsaXN0X3JlbW92ZSgmZGRyYXctPmRkcmF3X2xpc3RfZW50cnkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2xpc3RfY3MpOwp9Cg==