LyogICAgICAgIERpcmVjdERyYXcgQmFzZSBGdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTctMTk5OSBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyB0aGUgKGludGVybmFsKSBkcml2ZXIgcmVnaXN0cmF0aW9uIGZ1bmN0aW9ucywKICogZHJpdmVyIGVudW1lcmF0aW9uIEFQSXMgYW5kIERpcmVjdERyYXcgY3JlYXRpb24gZnVuY3Rpb25zLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCgp0eXBlZGVmIElXaW5lRDNEKiAoV0lOQVBJICpmbldpbmVEaXJlY3QzRENyZWF0ZSkoVUlOVCwgVUlOVCwgSVVua25vd24gKik7CgpzdGF0aWMgSE1PRFVMRSBoV2luZUQzRCA9IChITU9EVUxFKSAtMTsKc3RhdGljIGZuV2luZURpcmVjdDNEQ3JlYXRlIHBXaW5lRGlyZWN0M0RDcmVhdGU7CgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgovKiBUaGUgY29uZmlndXJlZCBkZWZhdWx0IHN1cmZhY2UgKi8KV0lORUQzRFNVUkZUWVBFIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfVU5LTk9XTjsKCi8qIEREcmF3IGxpc3QgYW5kIGNyaXRpY2FsIHNlY3Rpb24gKi8Kc3RhdGljIHN0cnVjdCBsaXN0IGdsb2JhbF9kZHJhd19saXN0ID0gTElTVF9JTklUKGdsb2JhbF9kZHJhd19saXN0KTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGRkcmF3X2NzX2RlYnVnID0KewogICAgMCwgMCwgJmRkcmF3X2NzLAogICAgeyAmZGRyYXdfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwKICAgICZkZHJhd19jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGRkcmF3X2NzIikgfQp9OwpDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2NzID0geyAmZGRyYXdfY3NfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogSGVscGVyIGZ1bmN0aW9uIGZvciBEaXJlY3REcmF3Q3JlYXRlIGFuZCBmcmllbmRzCiAqIENyZWF0ZXMgYSBuZXcgRERyYXcgaW50ZXJmYWNlIHdpdGggdGhlIGdpdmVuIFJFRklJRAogKgogKiBJbnRlcmZhY2VzIHRoYXQgY2FuIGJlIGNyZWF0ZWQ6CiAqICBJRGlyZWN0RHJhdywgSURpcmVjdERyYXcyLCBJRGlyZWN0RHJhdzQsIElEaXJlY3REcmF3NwogKiAgSURpcmVjdDNELCBJRGlyZWN0M0QyLCBJRGlyZWN0M0QzLCBJRGlyZWN0M0Q3LiAoRG9lcyBXaW5kb3dzIHJldHVybgogKiAgSURpcmVjdDNEIGludGVyZmFjZXM/KQogKgogKiBBcmd1bWVudHM6CiAqICBndWlkOiBJRCBvZiB0aGUgcmVxdWVzdGVkIGRyaXZlciwgTlVMTCBmb3IgdGhlIGRlZmF1bHQgZHJpdmVyLgogKiAgICAgICAgVGhlIEdVSUQgY2FuIGJlIHF1ZXJpZWQgd2l0aCBEaXJlY3REcmF3RW51bWVyYXRlKEV4KUEvVwogKiAgREQ6IFVzZWQgdG8gcmV0dXJuIHRoZSBwb2ludGVyIHRvIHRoZSBjcmVhdGVkIG9iamVjdAogKiAgVW5rT3V0ZXI6IEZvciBhZ2dyZWdhdGlvbiwgd2hpY2ggaXMgdW5zdXBwb3J0ZWQuIE11c3QgYmUgTlVMTAogKiAgaWlkOiByZXF1ZXN0ZWQgdmVyc2lvbiBJRC4KICoKICogUmV0dXJuczoKICogIEREX09LIGlmIHRoZSBJbnRlcmZhY2Ugd2FzIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgaXMgbm90IE5VTEwKICogIEVfT1VUT0ZNRU1PUlkgaWYgc29tZSBhbGxvY2F0aW9uIGZhaWxlZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCkREUkFXX0NyZWF0ZShjb25zdCBHVUlEICpndWlkLAogICAgICAgICAgICAgdm9pZCAqKkRELAogICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyLAogICAgICAgICAgICAgUkVGSUlEIGlpZCkKewogICAgSURpcmVjdERyYXdJbXBsICpUaGlzID0gTlVMTDsKICAgIEhSRVNVTFQgaHI7CiAgICBJV2luZUQzRCAqd2luZUQzRCA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZSAqd2luZUQzRERldmljZSA9IE5VTEw7CiAgICBIREMgaERDOwogICAgV0lORUQzRERFVlRZUEUgZGV2aWNldHlwZTsKCiAgICBUUkFDRSgiKCVzLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgREQsIFVua091dGVyKTsKCiAgICAqREQgPSBOVUxMOwoKICAgIC8qIFdlIGRvbid0IGNhcmUgYWJvdXQgdGhpcyBndWlkcy4gV2VsbCwgdGhlcmUncyBubyBzcGVjaWFsIGd1aWQgYW55d2F5CiAgICAgKiBPSywgd2UgY291bGQKICAgICAqLwogICAgaWYgKGd1aWQgPT0gKEdVSUQgKikgRERDUkVBVEVfRU1VTEFUSU9OT05MWSkKICAgIHsKICAgICAgICAvKiBVc2UgdGhlIHJlZmVyZW5jZSBkZXZpY2UgaWQuIFRoaXMgZG9lc24ndCBhY3R1YWxseSBjaGFuZ2UgYW55dGhpbmcsCiAgICAgICAgICogV2luZUQzRCBhbHdheXMgdXNlcyBPcGVuR0wgZm9yIEQzRCByZW5kZXJpbmcuIE9uZSBjb3VsZCBtYWtlIGl0IHJlcXVlc3QKICAgICAgICAgKiBpbmRpcmVjdCByZW5kZXJpbmcKICAgICAgICAgKi8KICAgICAgICBkZXZpY2V0eXBlID0gV0lORUQzRERFVlRZUEVfUkVGOwogICAgfQogICAgZWxzZSBpZihndWlkID09IChHVUlEICopIEREQ1JFQVRFX0hBUkRXQVJFT05MWSkKICAgIHsKICAgICAgICBkZXZpY2V0eXBlID0gV0lORUQzRERFVlRZUEVfSEFMOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGRldmljZXR5cGUgPSAwOwogICAgfQoKICAgIC8qIEREcmF3IGRvZXNuJ3Qgc3VwcG9ydCBhZ2dyZWdhdGlvbiwgYWNjb3JkaW5nIHRvIG1zZG4gKi8KICAgIGlmIChVbmtPdXRlciAhPSBOVUxMKQogICAgICAgIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgLyogRGlyZWN0RHJhdyBjcmVhdGlvbiBjb21lcyBoZXJlICovCiAgICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRGlyZWN0RHJhd0ltcGwpKTsKICAgIGlmKCFUaGlzKQogICAgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGNyZWF0aW5nIERpcmVjdERyYXdcbiIpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIC8qIFRoZSBpbnRlcmZhY2VzOgogICAgICogSURpcmVjdERyYXcgYW5kIElEaXJlY3QzRCBhcmUgdGhlIHNhbWUgb2JqZWN0LAogICAgICogUXVlcnlJbnRlcmZhY2UgaXMgdXNlZCB0byBnZXQgb3RoZXIgaW50ZXJmYWNlcy4KICAgICAqLwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdywgIElEaXJlY3REcmF3MV9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcyLCBJRGlyZWN0RHJhdzJfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3MywgSURpcmVjdERyYXczX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzQsIElEaXJlY3REcmF3NF9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3LCBJRGlyZWN0RHJhdzdfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRCwgIElEaXJlY3QzRDFfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDIsIElEaXJlY3QzRDJfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDMsIElEaXJlY3QzRDNfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDcsIElEaXJlY3QzRDdfVnRibCk7CgogICAgLyogU2VlIGNvbW1lbnRzIGluIElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlIGZvciBhIGRlc2NyaXB0aW9uCiAgICAgKiBvZiB0aGlzIG1lbWJlci4KICAgICAqIFJlYWQgZnJvbSBhIHJlZ2lzdHJ5IGtleSwgc2hvdWxkIGFkZCBhIHdpbmVjZmcgb3B0aW9uIGxhdGVyCiAgICAgKi8KICAgIFRoaXMtPkltcGxUeXBlID0gRGVmYXVsdFN1cmZhY2VUeXBlOwoKICAgIC8qIEdldCB0aGUgY3VycmVudCBzY3JlZW4gc2V0dGluZ3MgKi8KICAgIGhEQyA9IEdldERDKDApOwogICAgVGhpcy0+b3JpZ19icHAgPSBHZXREZXZpY2VDYXBzKGhEQywgQklUU1BJWEVMKSAqIEdldERldmljZUNhcHMoaERDLCBQTEFORVMpOwogICAgUmVsZWFzZURDKDAsIGhEQyk7CiAgICBUaGlzLT5vcmlnX3dpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTik7CiAgICBUaGlzLT5vcmlnX2hlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pOwoKICAgIGlmIChoV2luZUQzRCA9PSAoSE1PRFVMRSkgLTEpCiAgICB7CiAgICAgICAgaFdpbmVEM0QgPSBMb2FkTGlicmFyeUEoIndpbmVkM2QiKTsKICAgICAgICBpZiAoaFdpbmVEM0QpCiAgICAgICAgewogICAgICAgICAgICBwV2luZURpcmVjdDNEQ3JlYXRlID0gKGZuV2luZURpcmVjdDNEQ3JlYXRlKSBHZXRQcm9jQWRkcmVzcyhoV2luZUQzRCwgIldpbmVEaXJlY3QzRENyZWF0ZSIpOwogICAgICAgICAgICBwV2luZURpcmVjdDNEQ3JlYXRlQ2xpcHBlciA9IChmbldpbmVEaXJlY3QzRENyZWF0ZUNsaXBwZXIpIEdldFByb2NBZGRyZXNzKGhXaW5lRDNELCAiV2luZURpcmVjdDNEQ3JlYXRlQ2xpcHBlciIpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoIWhXaW5lRDNEKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgbG9hZCBXaW5lRDNEIC0gT3BlbkdMIGxpYnMgbm90IHByZXNlbnQ/XG4iKTsKICAgICAgICBociA9IERERVJSX05PRElSRUNURFJBV1NVUFBPUlQ7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgV2luZUQzRAogICAgICoKICAgICAqIEFsbCBSZW5kZXJpbmcgKDJEIGFuZCAzRCkgaXMgcmVsYXllZCB0byBXaW5lRDNELAogICAgICogYnV0IERpcmVjdERyYXcgc3BlY2lmaWMgbWFuYWdlbWVudCwgbGlrZSBERFNVUkZBQ0VERVNDIGFuZCBERFBJWEVMRk9STUFUCiAgICAgKiBzdHJ1Y3R1cmUgaGFuZGxpbmcgaXMgaGFuZGxlZCBpbiB0aGlzIGxpYi4KICAgICAqLwogICAgd2luZUQzRCA9IHBXaW5lRGlyZWN0M0RDcmVhdGUoMCAvKiBTREtWZXJzaW9uICovLCA3IC8qIERYVmVyc2lvbiAqLywgKElVbmtub3duICopIFRoaXMgLyogUGFyZW50ICovKTsKICAgIGlmKCF3aW5lRDNEKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGluaXRpYWxpc2UgV2luZUQzRFxuIik7CiAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KICAgIFRoaXMtPndpbmVEM0QgPSB3aW5lRDNEOwogICAgVFJBQ0UoIldpbmVEM0QgY3JlYXRlZCBhdCAlcFxuIiwgd2luZUQzRCk7CgogICAgLyogSW5pdGlhbGl6ZWQgbWVtYmVyLi4uCiAgICAgKgogICAgICogSXQgaXMgc2V0IHRvIGZhbHNlIGF0IGNyZWF0aW9uIHRpbWUsIGFuZCBzZXQgdG8gdHJ1ZSBpbgogICAgICogSURpcmVjdERyYXc3OjpJbml0aWFsaXplLiBJdHMgc29sZSBwdXJwb3NlIGlzIHRvIHJldHVybiBERF9PSyBvbgogICAgICogaW5pdGlhbGl6ZSBvbmx5IG9uY2UKICAgICAqLwogICAgVGhpcy0+aW5pdGlhbGl6ZWQgPSBGQUxTRTsKCiAgICAvKiBJbml0aWFsaXplIFdpbmVEM0REZXZpY2UKICAgICAqCiAgICAgKiBJdCBpcyB1c2VkIGZvciBzY3JlZW4gc2V0dXAsIHN1cmZhY2UgYW5kIHBhbGV0dGUgY3JlYXRpb24KICAgICAqIFdoZW4gYSBEaXJlY3QzRERldmljZTcgaXMgY3JlYXRlZCwgdGhlIEQzRCBjYXBhYmlsaXRpZXMgb2YgV2luZUQzRCBhcmUKICAgICAqIGluaXRpYWxpemVkCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RfQ3JlYXRlRGV2aWNlKHdpbmVEM0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qRDNEX0FEQVBURVJfREVGQVVMVCovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNldHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIC8qIEZvY3VzV2luZG93LCBkb24ndCBrbm93IHlldCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogQmVoYXZpb3JGbGFncyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIHdpbmVEM0REZXZpY2UsIHJlc3VsdCA9ICV4XG4iLCBocik7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQogICAgVGhpcy0+d2luZUQzRERldmljZSA9IHdpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgid2luZUQzRERldmljZSBjcmVhdGVkIGF0ICVwXG4iLCBUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICAvKiBSZWdpc3RlciB0aGUgd2luZG93IGNsYXNzCiAgICAgKgogICAgICogSXQgaXMgdXNlZCB0byBjcmVhdGUgYSBoaWRkZW4gd2luZG93IGZvciBEM0QKICAgICAqIHJlbmRlcmluZywgaWYgdGhlIGFwcGxpY2F0aW9uIGRpZG4ndCBwYXNzIG9uZS4KICAgICAqIEl0IGNhbiBhbHNvIGJlIHVzZWQgZm9yIENyZWF0aW5nIGEgZGV2aWNlIHdpbmRvdwogICAgICogZnJvbSBTZXRDb29wZXJhdGl2ZUxldmVsCiAgICAgKgogICAgICogVGhlIG5hbWU6IEREUkFXXzxhZGRyZXNzPi4gVGhlIGNsYXNzbmFtZSBpcwogICAgICogMzIgYml0IGxvbmcsIHNvIGEgNjQgYml0IGFkZHJlc3Mgd2lsbCBmaXQgbmljZWx5CiAgICAgKiAoV2lsbCB0aGlzIGJlIGNvbXBpbGVkIGZvciA2NCBiaXQgYW55d2F5PykKICAgICAqCiAgICAgKi8KICAgIHNwcmludGYoVGhpcy0+Y2xhc3NuYW1lLCAiRERSQVdfJXAiLCBUaGlzKTsKCiAgICBtZW1zZXQoJlRoaXMtPnduZF9jbGFzcywgMCwgc2l6ZW9mKFRoaXMtPnduZF9jbGFzcykpOwogICAgVGhpcy0+d25kX2NsYXNzLnN0eWxlID0gQ1NfSFJFRFJBVyB8IENTX1ZSRURSQVc7CiAgICBUaGlzLT53bmRfY2xhc3MubHBmblduZFByb2MgPSBEZWZXaW5kb3dQcm9jQTsKICAgIFRoaXMtPnduZF9jbGFzcy5jYkNsc0V4dHJhID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5jYlduZEV4dHJhID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oSW5zdGFuY2UgPSBHZXRNb2R1bGVIYW5kbGVBKDApOwogICAgVGhpcy0+d25kX2NsYXNzLmhJY29uID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oQ3Vyc29yID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkgR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgVGhpcy0+d25kX2NsYXNzLmxwc3pNZW51TmFtZSA9IE5VTEw7CiAgICBUaGlzLT53bmRfY2xhc3MubHBzekNsYXNzTmFtZSA9IFRoaXMtPmNsYXNzbmFtZTsKICAgIGlmKCFSZWdpc3RlckNsYXNzQSgmVGhpcy0+d25kX2NsYXNzKSkKICAgIHsKICAgICAgICBFUlIoIlJlZ2lzdGVyQ2xhc3NBIGZhaWxlZCFcbiIpOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIGFtb3VudCBvZiB2aWRlbyBtZW1vcnkgKi8KICAgIFRoaXMtPnRvdGFsX3ZpZG1lbSA9IElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgY2FwcyAqLwogICAgVGhpcy0+Y2Fwcy5kd1NpemUgPSBzaXplb2YoVGhpcy0+Y2Fwcyk7Ci8qIGRvIG5vdCByZXBvcnQgRERDQVBTX09WRVJMQVkgYW5kIGZyaWVuZHMgc2luY2Ugd2UgZG9uJ3Qgc3VwcG9ydCBvdmVybGF5cyAqLwojZGVmaW5lIEJMSVRfQ0FQUyAoRERDQVBTX0JMVCB8IEREQ0FQU19CTFRDT0xPUkZJTEwgfCBERENBUFNfQkxUREVQVEhGSUxMIFwKICAgICAgICAgIHwgRERDQVBTX0JMVFNUUkVUQ0ggfCBERENBUFNfQ0FOQkxUU1lTTUVNIHwgRERDQVBTX0NBTkNMSVAJICBcCiAgICAgICAgICB8IEREQ0FQU19DQU5DTElQU1RSRVRDSEVEIHwgRERDQVBTX0NPTE9SS0VZCQkJICBcCiAgICAgICAgICB8IEREQ0FQU19DT0xPUktFWUhXQVNTSVNUIHwgRERDQVBTX0FMSUdOQk9VTkRBUllTUkMgKQojZGVmaW5lIENLRVlfQ0FQUyAoRERDS0VZQ0FQU19ERVNUQkxUIHwgRERDS0VZQ0FQU19TUkNCTFQpCiNkZWZpbmUgRlhfQ0FQUyAoRERGWENBUFNfQkxUQUxQSEEgfCBEREZYQ0FQU19CTFRNSVJST1JMRUZUUklHSFQJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRNSVJST1JVUERPV04gfCBEREZYQ0FQU19CTFRST1RBVElPTjkwCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUU0hSSU5LWCB8IERERlhDQVBTX0JMVFNIUklOS1hOCQlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNIUklOS1kgfCBEREZYQ0FQU19CTFRTSFJJTktYTgkJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTVFJFVENIWCB8IERERlhDQVBTX0JMVFNUUkVUQ0hYTgkJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTVFJFVENIWSB8IERERlhDQVBTX0JMVFNUUkVUQ0hZTikKICAgIFRoaXMtPmNhcHMuZHdDYXBzIHw9IEREQ0FQU19HREkgfCBERENBUFNfUEFMRVRURSB8IEJMSVRfQ0FQUzsKCiAgICBUaGlzLT5jYXBzLmR3Q2FwczIgfD0gRERDQVBTMl9DRVJUSUZJRUQgfCBERENBUFMyX05PUEFHRUxPQ0tSRVFVSVJFRCB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTMl9QUklNQVJZR0FNTUEgfCBERENBUFMyX1dJREVTVVJGQUNFUyB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTMl9DQU5SRU5ERVJXSU5ET1dFRDsKICAgIFRoaXMtPmNhcHMuZHdDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3RlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3UGFsQ2FwcyB8PSBERFBDQVBTXzhCSVQgfCBERFBDQVBTX1BSSU1BUllTVVJGQUNFOwogICAgVGhpcy0+Y2Fwcy5kd1ZpZE1lbVRvdGFsID0gVGhpcy0+dG90YWxfdmlkbWVtOwogICAgVGhpcy0+Y2Fwcy5kd1ZpZE1lbUZyZWUgPSBUaGlzLT50b3RhbF92aWRtZW07CiAgICBUaGlzLT5jYXBzLmR3U1ZCQ2FwcyB8PSBCTElUX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1ZCQ0tleUNhcHMgfD0gQ0tFWV9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NWQkZYQ2FwcyB8PSBGWF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkNhcHMgfD0gQkxJVF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkNLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdWU0JGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JDYXBzIHw9IEJMSVRfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1NCRlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfQUxQSEEgfCBERFNDQVBTX0JBQ0tCVUZGRVIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX0ZMSVAgfCBERFNDQVBTX0ZST05UQlVGRkVSIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19PRkZTQ1JFRU5QTEFJTiB8IEREU0NBUFNfUEFMRVRURSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTX1NZU1RFTU1FTU9SWSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfVklERU9NRU1PUlkgfCBERFNDQVBTX1ZJU0lCTEU7CiAgICAvKiBIYWNrcyBmb3IgRDNEIGNvZGUgKi8KICAgIC8qIFRPRE86IENoZWNrIGlmIFdpbmVEM0QgaGFzIDNEIGVuYWJsZWQKICAgICAgIE5lZWQgb3BlbmdsIHN1cmZhY2VzIG9yIGF1dG8gZm9yIDNECiAgICAgKi8KICAgIGlmKFRoaXMtPkltcGxUeXBlID09IDAgfHwgVGhpcy0+SW1wbFR5cGUgPT0gU1VSRkFDRV9PUEVOR0wpCiAgICB7CiAgICAgICAgVGhpcy0+Y2Fwcy5kd0NhcHMgfD0gRERDQVBTXzNEOwogICAgICAgIFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU18zRERFVklDRSB8IEREU0NBUFNfTUlQTUFQIHwgRERTQ0FQU19URVhUVVJFIHwgRERTQ0FQU19aQlVGRkVSOwogICAgfQogICAgVGhpcy0+Y2Fwcy5kZHNPbGRDYXBzLmR3Q2FwcyA9IFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHM7CgojdW5kZWYgQkxJVF9DQVBTCiN1bmRlZiBDS0VZX0NBUFMKI3VuZGVmIEZYX0NBUFMKCiAgICBsaXN0X2luaXQoJlRoaXMtPnN1cmZhY2VfbGlzdCk7CiAgICBsaXN0X2FkZF9oZWFkKCZnbG9iYWxfZGRyYXdfbGlzdCwgJlRoaXMtPmRkcmF3X2xpc3RfZW50cnkpOwoKICAgIC8qIENhbGwgUXVlcnlJbnRlcmZhY2UgdG8gZ2V0IHRoZSBwb2ludGVyIHRvIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLiBUaGlzIGFsc28gaW5pdGlhbGl6ZXMKICAgICAqIFRoZSByZXF1aXJlZCByZWZjb3VudAogICAgICovCiAgICBociA9IElEaXJlY3REcmF3N19RdWVyeUludGVyZmFjZSggSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwgaWlkLCBERCk7CiAgICBpZihTVUNDRUVERUQoaHIpKSByZXR1cm4gRERfT0s7CgplcnJfb3V0OgogICAgLyogTGV0J3MgaG9wZSB3ZSBuZXZlciBuZWVkIHRoaXMgOykgKi8KICAgIGlmKHdpbmVEM0REZXZpY2UpIElXaW5lRDNERGV2aWNlX1JlbGVhc2Uod2luZUQzRERldmljZSk7CiAgICBpZih3aW5lRDNEKSBJV2luZUQzRF9SZWxlYXNlKHdpbmVEM0QpOwogICAgaWYoVGhpcykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZGVjbHMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3Q3JlYXRlIChERFJBVy5AKQogKgogKiBDcmVhdGVzIGxlZ2FjeSBEaXJlY3REcmF3IEludGVyZmFjZXMuIENhbid0IGNyZWF0ZSBJRGlyZWN0RHJhdzcKICogaW50ZXJmYWNlcyBpbiB0aGVvcnkKICoKICogQXJndW1lbnRzLCByZXR1cm4gdmFsdWVzOiBTZWUgRERSQVdfQ3JlYXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0NyZWF0ZShHVUlEICpHVUlELAogICAgICAgICAgICAgICAgIElEaXJlY3REcmF3ICoqREQsCiAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQoR1VJRCksIERELCBVbmtPdXRlcik7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gRERSQVdfQ3JlYXRlKEdVSUQsICh2b2lkICoqKSBERCwgVW5rT3V0ZXIsICZJSURfSURpcmVjdERyYXcpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdDcmVhdGVFeCAoRERSQVcuQCkKICoKICogT25seSBjcmVhdGVzIG5ldyBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlcywgc3VwcG9zZWQgdG8gZmFpbCBpZiBsZWdhY3kKICogaW50ZXJmYWNlcyBhcmUgcmVxdWVzdGVkLgogKgogKiBBcmd1bWVudHMsIHJldHVybiB2YWx1ZXM6IFNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpEaXJlY3REcmF3Q3JlYXRlRXgoR1VJRCAqR1VJRCwKICAgICAgICAgICAgICAgICAgIHZvaWQgKipERCwKICAgICAgICAgICAgICAgICAgIFJFRklJRCBpaWQsCiAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVzLCVwLCVzLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChHVUlEKSwgREQsIGRlYnVnc3RyX2d1aWQoaWlkKSwgVW5rT3V0ZXIpOwoKICAgIGlmICghSXNFcXVhbEdVSUQoaWlkLCAmSUlEX0lEaXJlY3REcmF3NykpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gRERSQVdfQ3JlYXRlKEdVSUQsIERELCBVbmtPdXRlciwgaWlkKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlQSAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBsZWdhY3kgZGRyYXcgZHJpdmVycywgYXNjaWkgdmVyc2lvbi4gV2Ugb25seSBoYXZlIG9uZQogKiBkcml2ZXIsIHdoaWNoIHJlbGF5cyB0byBXaW5lRDNELiBJZiB3ZSB3ZXJlIHN1ZmZpY2llbnRseSBjb29sLAogKiB3ZSBjb3VsZCBvZmZlciB2YXJpb3VzIGludGVyZmFjZXMsIHdoaWNoIHVzZSBhIGRpZmZlcmVudCBkZWZhdWx0IHN1cmZhY2UKICogaW1wbGVtZW50YXRpb24sIGJ1dCBJIHRoaW5rIGl0J3MgYmV0dGVyIHRvIG9mZmVyIHRoaXMgY2hvaWNlIGluCiAqIHdpbmVjZmcsIGJlY2F1c2Ugc29tZSBhcHBzIHVzZSB0aGUgZGVmYXVsdCBkcml2ZXIsIHNvIHdlIHdvdWxkIG5lZWQKICogYSB3aW5lY2ZnIG9wdGlvbiBhbnl3YXksIGFuZCB0aGVyZSBzaG91bGRuJ3QgYmUgMiB3YXlzIHRvIHNldCBvbmUgc2V0dGluZwogKgogKiBBcmd1bWVudHM6CiAqICBDYWxsYmFjazogQ2FsbGJhY2sgZnVuY3Rpb24gZnJvbSB0aGUgYXBwCiAqICBDb250ZXh0OiBBcmd1bWVudCB0byB0aGUgY2FsbCBiYWNrLgogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRV9JTlZBTElEQVJHIGlmIHRoZSBDYWxsYmFjayBjYXVzZWQgYSBwYWdlIGZhdWx0CiAqCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0VudW1lcmF0ZUEoTFBEREVOVU1DQUxMQkFDS0EgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkNvbnRleHQpCnsKICAgIEJPT0wgc3RvcCA9IEZBTFNFOwoKICAgIFRSQUNFKCIgRW51bWVyYXRpbmcgZGVmYXVsdCBEaXJlY3REcmF3IEhBTCBpbnRlcmZhY2VcbiIpOwogICAgLyogV2Ugb25seSBoYXZlIG9uZSBkcml2ZXIgKi8KICAgIF9fVFJZCiAgICB7CiAgICAgICAgc3RhdGljIENIQVIgZHJpdmVyX2Rlc2NbXSA9ICJEaXJlY3REcmF3IEhBTCIsCiAgICAgICAgZHJpdmVyX25hbWVbXSA9ICJkaXNwbGF5IjsKCiAgICAgICAgc3RvcCA9ICFDYWxsYmFjayhOVUxMLCBkcml2ZXJfZGVzYywgZHJpdmVyX25hbWUsIENvbnRleHQpOwogICAgfQogICAgX19FWENFUFRfUEFHRV9GQVVMVAogICAgewogICAgICAgIHJldHVybiBFX0lOVkFMSURBUkc7CiAgICB9CiAgICBfX0VORFRSWQoKICAgIFRSQUNFKCIgRW5kIG9mIGVudW1lcmF0aW9uXG4iKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdFbnVtZXJhdGVFeEEgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgRGlyZWN0RHJhdzcgZHJpdmVycywgYXNjaWkgdmVyc2lvbi4gU2VlCiAqIHRoZSBjb21tZW50cyBhYm92ZSBEaXJlY3REcmF3RW51bWVyYXRlQSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgRmxhZyBtZW1iZXIgaXMgbm90IHN1cHBvcnRlZCByaWdodCBub3cuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0VudW1lcmF0ZUV4QShMUERERU5VTUNBTExCQUNLRVhBIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIEJPT0wgc3RvcCA9IEZBTFNFOwogICAgVFJBQ0UoIkVudW1lcmF0aW5nIGRlZmF1bHQgRGlyZWN0RHJhdyBIQUwgaW50ZXJmYWNlXG4iKTsKCiAgICAvKiBXZSBvbmx5IGhhdmUgb25lIGRyaXZlciBieSBub3cgKi8KICAgIF9fVFJZCiAgICB7CiAgICAgICAgc3RhdGljIENIQVIgZHJpdmVyX2Rlc2NbXSA9ICJEaXJlY3REcmF3IEhBTCIsCiAgICAgICAgZHJpdmVyX25hbWVbXSA9ICJkaXNwbGF5IjsKCiAgICAgICAgLyogUXVpY2tUaW1lIGV4cGVjdHMgdGhlIGRlc2NyaXB0aW9uICJEaXJlY3REcmF3IEhBTCIgKi8KICAgICAgICBzdG9wID0gIUNhbGxiYWNrKE5VTEwsIGRyaXZlcl9kZXNjLCBkcml2ZXJfbmFtZSwgQ29udGV4dCwgMCk7CiAgICB9CiAgICBfX0VYQ0VQVF9QQUdFX0ZBVUxUCiAgICB7CiAgICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKICAgIH0KICAgIF9fRU5EVFJZOwoKICAgIFRSQUNFKCJFbmQgb2YgZW51bWVyYXRpb25cbiIpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZVcgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgbGVnYWN5IGRyaXZlcnMsIHVuaWNvZGUgdmVyc2lvbi4gU2VlCiAqIHRoZSBjb21tZW50cyBhYm92ZSBEaXJlY3REcmF3RW51bWVyYXRlQSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgRmxhZyBtZW1iZXIgaXMgbm90IHN1cHBvcnRlZCByaWdodCBub3cuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlRXhXIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIERpcmVjdERyYXc3IGRyaXZlcnMsIHVuaWNvZGUgdmVyc2lvbi4gU2VlCiAqIHRoZSBjb21tZW50cyBhYm92ZSBEaXJlY3REcmF3RW51bWVyYXRlQSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgRmxhZyBtZW1iZXIgaXMgbm90IHN1cHBvcnRlZCByaWdodCBub3cuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDbGFzc2ZhY3RvcnkgaW1wbGVtZW50YXRpb24uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDRl9DcmVhdGVEaXJlY3REcmF3CiAqCiAqIEREcmF3IGNyZWF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgY2xhc3MgZmFjdG9yeQogKgogKiBQYXJhbXM6CiAqICBVbmtPdXRlcjogU2V0IHRvIE5VTEwKICogIGlpZDogSUQgb2YgdGhlIHdhbnRlZCBpbnRlcmZhY2UKICogIG9iajogQWRkcmVzcyB0byBwYXNzIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBiYWNrCiAqCiAqIFJldHVybnMKICogIEREX09LIC8gRERFUlIqLCBzZWUgRERSQVdfQ3JlYXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKQ0ZfQ3JlYXRlRGlyZWN0RHJhdyhJVW5rbm93biogVW5rT3V0ZXIsIFJFRklJRCBpaWQsCiAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVW5rT3V0ZXIsIGRlYnVnc3RyX2d1aWQoaWlkKSwgb2JqKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBERFJBV19DcmVhdGUoTlVMTCwgb2JqLCBVbmtPdXRlciwgaWlkKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDRl9DcmVhdGVEaXJlY3REcmF3CiAqCiAqIENsaXBwZXIgY3JlYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFBhcmFtczoKICogIFVua091dGVyOiBTZXQgdG8gTlVMTAogKiAgaWlkOiBJRCBvZiB0aGUgd2FudGVkIGludGVyZmFjZQogKiAgb2JqOiBBZGRyZXNzIHRvIHBhc3MgdGhlIGludGVyZmFjZSBwb2ludGVyIGJhY2sKICoKICogUmV0dXJucwogKiAgRERfT0sgLyBEREVSUiosIHNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApDRl9DcmVhdGVEaXJlY3REcmF3Q2xpcHBlcihJVW5rbm93biogVW5rT3V0ZXIsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSURpcmVjdERyYXdDbGlwcGVyICpDbGlwOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IERpcmVjdERyYXdDcmVhdGVDbGlwcGVyKDAsICZDbGlwLCBVbmtPdXRlcik7CiAgICBpZiAoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaHIgPSBJRGlyZWN0RHJhd0NsaXBwZXJfUXVlcnlJbnRlcmZhY2UoQ2xpcCwgcmlpZCwgb2JqKTsKICAgIElEaXJlY3REcmF3Q2xpcHBlcl9SZWxlYXNlKENsaXApOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3Qgb2JqZWN0X2NyZWF0aW9uX2luZm8gb2JqZWN0X2NyZWF0aW9uW10gPQp7CiAgICB7ICZDTFNJRF9EaXJlY3REcmF3LCAgICAgICAgQ0ZfQ3JlYXRlRGlyZWN0RHJhdyB9LAogICAgeyAmQ0xTSURfRGlyZWN0RHJhdzcsICAgICAgIENGX0NyZWF0ZURpcmVjdERyYXcgfSwKICAgIHsgJkNMU0lEX0RpcmVjdERyYXdDbGlwcGVyLCBDRl9DcmVhdGVEaXJlY3REcmF3Q2xpcHBlciB9Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6UXVlcnlJbnRlcmZhY2UKICoKICogUXVlcnlJbnRlcmZhY2UgZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFBBUkFNUwogKiAgICByaWlkICAgUmVmZXJlbmNlIHRvIGlkZW50aWZpZXIgb2YgcXVlcmllZCBpbnRlcmZhY2UKICogICAgcHB2ICAgIEFkZHJlc3MgdG8gcmV0dXJuIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBhdAogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9RdWVyeUludGVyZmFjZShJQ2xhc3NGYWN0b3J5ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYmopOwoKICAgIGlmIChJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lVbmtub3duKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSUNsYXNzRmFjdG9yeSkpCiAgICB7CiAgICAgICAgSUNsYXNzRmFjdG9yeV9BZGRSZWYoaWZhY2UpOwogICAgICAgICpvYmogPSBUaGlzOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIFdBUk4oIiglcCktPiglcywlcCksbm90IGZvdW5kXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpBZGRSZWYKICoKICogQWRkUmVmIGZvciB0aGUgY2xhc3MgZmFjdG9yeQogKgogKiBSRVRVUk5TCiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9BZGRSZWYoSUNsYXNzRmFjdG9yeSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgaW5jcmVtZW50aW5nIGZyb20gJWQuXG4iLCBUaGlzLCByZWYgLSAxKTsKCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6UmVsZWFzZQogKgogKiBSZWxlYXNlIGZvciB0aGUgY2xhc3MgZmFjdG9yeS4gSWYgdGhlIHJlZmNvdW50IGZhbGxzIHRvIDAsIHRoZSBvYmplY3QKICogaXMgZGVzdHJveWVkCiAqCiAqIFJFVFVSTlMKICogIFRoZSBuZXcgcmVmY291bnQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1JlbGVhc2UoSUNsYXNzRmFjdG9yeSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIFRSQUNFKCIoJXApLT4oKSBkZWNyZW1lbnRpbmcgZnJvbSAlZC5cbiIsIFRoaXMsIHJlZisxKTsKCiAgICBpZiAocmVmID09IDApCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CgogICAgcmV0dXJuIHJlZjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpDcmVhdGVJbnN0YW5jZQogKgogKiBXaGF0IGlzIHRoaXM/IFNlZW1zIHRvIGNyZWF0ZSBEaXJlY3REcmF3IG9iamVjdHMuLi4KICoKICogUGFyYW1zCiAqICBUaGUgdXN1c2FsIHRoaW5ncz8/PwogKgogKiBSRVRVUk5TCiAqICA/Pz8KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQ3JlYXRlSW5zdGFuY2UoSUNsYXNzRmFjdG9yeSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcywlcClcbiIsVGhpcyxVbmtPdXRlcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CgogICAgcmV0dXJuIFRoaXMtPnBmbkNyZWF0ZUluc3RhbmNlKFVua091dGVyLCByaWlkLCBvYmopOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6TG9ja1NlcnZlcgogKgogKiBXaGF0IGlzIHRoaXM/CiAqCiAqIFBhcmFtcwogKiAgPz8/CiAqCiAqIFJFVFVSTlMKICogIFNfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfTG9ja1NlcnZlcihJQ2xhc3NGYWN0b3J5ICppZmFjZSxCT09MIGRvbG9jaykKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJWQpLHN0dWIhXG4iLFRoaXMsZG9sb2NrKTsKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgY2xhc3MgZmFjdG9yeSBWVGFibGUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBjb25zdCBJQ2xhc3NGYWN0b3J5VnRibCBJQ2xhc3NGYWN0b3J5X1Z0YmwgPQp7CiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQWRkUmVmLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1JlbGVhc2UsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQ3JlYXRlSW5zdGFuY2UsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfTG9ja1NlcnZlcgp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsR2V0Q2xhc3NPYmplY3QgW0REUkFXLkBdCiAqIFJldHJpZXZlcyBjbGFzcyBvYmplY3QgZnJvbSBhIERMTCBvYmplY3QKICoKICogTk9URVMKICogICAgRG9jcyBzYXkgcmV0dXJucyBTVERBUEkKICoKICogUEFSQU1TCiAqICAgIHJjbHNpZCBbSV0gQ0xTSUQgZm9yIHRoZSBjbGFzcyBvYmplY3QKICogICAgcmlpZCAgIFtJXSBSZWZlcmVuY2UgdG8gaWRlbnRpZmllciBvZiBpbnRlcmZhY2UgZm9yIGNsYXNzIG9iamVjdAogKiAgICBwcHYgICAgW09dIEFkZHJlc3Mgb2YgdmFyaWFibGUgdG8gcmVjZWl2ZSBpbnRlcmZhY2UgcG9pbnRlciBmb3IgcmlpZAogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRSwgRV9PVVRPRk1FTU9SWSwgRV9JTlZBTElEQVJHLAogKiAgICAgICAgICAgICBFX1VORVhQRUNURUQKICovCkhSRVNVTFQgV0lOQVBJIERsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIElDbGFzc0ZhY3RvcnlJbXBsICpmYWN0b3J5OwoKICAgIFRSQUNFKCIoJXMsJXMsJXApXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCksIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdik7CgogICAgaWYgKCAhSXNFcXVhbEdVSUQoICZJSURfSUNsYXNzRmFjdG9yeSwgcmlpZCApCgkgJiYgISBJc0VxdWFsR1VJRCggJklJRF9JVW5rbm93biwgcmlpZCkgKQoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CgogICAgZm9yIChpPTA7IGkgPCBzaXplb2Yob2JqZWN0X2NyZWF0aW9uKS9zaXplb2Yob2JqZWN0X2NyZWF0aW9uWzBdKTsgaSsrKQogICAgewoJaWYgKElzRXF1YWxHVUlEKG9iamVjdF9jcmVhdGlvbltpXS5jbHNpZCwgcmNsc2lkKSkKCSAgICBicmVhazsKICAgIH0KCiAgICBpZiAoaSA9PSBzaXplb2Yob2JqZWN0X2NyZWF0aW9uKS9zaXplb2Yob2JqZWN0X2NyZWF0aW9uWzBdKSkKICAgIHsKCUZJWE1FKCIlczogbm8gY2xhc3MgZm91bmQuXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwoJcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7CiAgICB9CgogICAgZmFjdG9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKmZhY3RvcnkpKTsKICAgIGlmIChmYWN0b3J5ID09IE5VTEwpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoZmFjdG9yeSwgSUNsYXNzRmFjdG9yeSwgSUNsYXNzRmFjdG9yeV9WdGJsKTsKICAgIGZhY3RvcnktPnJlZiA9IDE7CgogICAgZmFjdG9yeS0+cGZuQ3JlYXRlSW5zdGFuY2UgPSBvYmplY3RfY3JlYXRpb25baV0ucGZuQ3JlYXRlSW5zdGFuY2U7CgogICAgKnBwdiA9IElDT01fSU5URVJGQUNFKGZhY3RvcnksIElDbGFzc0ZhY3RvcnkpOwogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxDYW5VbmxvYWROb3cgW0REUkFXLkBdICBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIERMTCBpcyBpbiB1c2UuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBTX0ZBTFNFCiAqLwpIUkVTVUxUIFdJTkFQSSBEbGxDYW5VbmxvYWROb3codm9pZCkKewogICAgSFJFU1VMVCBocjsKICAgIEZJWE1FKCIodm9pZCk6IHN0dWJcbiIpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IFNfRkFMU0U7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGVzdHJveUNhbGxiYWNrCiAqCiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciB0aGUgRW51bVN1cmZhY2VzIGNhbGwgaW4gRGxsTWFpbi4KICogRHVtcHMgc29tZSBzdXJmYWNlIGluZm8gYW5kIHJlbGVhc2VzIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIHN1cmY6IFRoZSBlbnVtZXJhdGVkIHN1cmZhY2UKICogIGRlc2M6IGl0J3MgZGVzY3JpcHRpb24KICogIGNvbnRleHQ6IFBvaW50ZXIgdG8gdGhlIGRkcmF3IGltcGwKICoKICogUmV0dXJuczoKICogIERERU5VTVJFVF9PSzsKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEZXN0cm95Q2FsbGJhY2soSURpcmVjdERyYXdTdXJmYWNlNyAqc3VyZiwKICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpkZXNjLAogICAgICAgICAgICAgICAgdm9pZCAqY29udGV4dCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqSW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHN1cmYpOwogICAgSURpcmVjdERyYXdJbXBsICpkZHJhdyA9IChJRGlyZWN0RHJhd0ltcGwgKikgY29udGV4dDsKICAgIFVMT05HIHJlZjsKCiAgICByZWYgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZik7ICAvKiBGb3IgdGhlIEVudW1TdXJmYWNlcyAqLwogICAgV0FSTigiU3VyZmFjZSAlcCBoYXMgYW4gcmVmZXJlbmNlIGNvdW50IG9mICVkXG4iLCBJbXBsLCByZWYpOwoKICAgIC8qIFNraXAgc3VyZmFjZXMgd2hpY2ggYXJlIGF0dGFjaGVkIHNvbWV3aGVyZSBvciB3aGljaCBhcmUKICAgICAqIHBhcnQgb2YgYSBjb21wbGV4IGNvbXBvdW5kLiBUaGV5IHdpbGwgZ2V0IHJlbGVhc2VkIHdoZW4gZGVzdHJveWluZwogICAgICogdGhlIHJvb3QKICAgICAqLwogICAgaWYoICghSW1wbC0+aXNfY29tcGxleF9yb290KSB8fCAoSW1wbC0+Zmlyc3RfYXR0YWNoZWQgIT0gSW1wbCkgKQogICAgICAgIHJldHVybiBEREVOVU1SRVRfT0s7CiAgICAvKiBTa2lwIG91ciBkZXB0aCBzdGVuY2lsIHN1cmZhY2UsIGl0IHdpbGwgYmUgcmVsZWFzZWQgd2l0aCB0aGUgcmVuZGVyIHRhcmdldCAqLwogICAgaWYoIEltcGwgPT0gZGRyYXctPkRlcHRoU3RlbmNpbEJ1ZmZlcikKICAgICAgICByZXR1cm4gRERFTlVNUkVUX09LOwoKICAgIC8qIERlc3Ryb3kgdGhlIHN1cmZhY2UgKi8KICAgIHdoaWxlKHJlZikgcmVmID0gSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmYpOwoKICAgIHJldHVybiBEREVOVU1SRVRfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfY29uZmlnX2tleQogKgogKiBSZWFkcyBhIGNvbmZpZyBrZXkgZnJvbSB0aGUgcmVnaXN0cnkuIFRha2VuIGZyb20gV2luZUQzRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBpbmxpbmUgRFdPUkQgZ2V0X2NvbmZpZ19rZXkoSEtFWSBkZWZrZXksIEhLRVkgYXBwa2V5LCBjb25zdCBjaGFyKiBuYW1lLCBjaGFyKiBidWZmZXIsIERXT1JEIHNpemUpCnsKICAgIGlmICgwICE9IGFwcGtleSAmJiAhUmVnUXVlcnlWYWx1ZUV4QSggYXBwa2V5LCBuYW1lLCAwLCBOVUxMLCAoTFBCWVRFKSBidWZmZXIsICZzaXplICkpIHJldHVybiAwOwogICAgaWYgKDAgIT0gZGVma2V5ICYmICFSZWdRdWVyeVZhbHVlRXhBKCBkZWZrZXksIG5hbWUsIDAsIE5VTEwsIChMUEJZVEUpIGJ1ZmZlciwgJnNpemUgKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxNYWluIChERFJBVy4wKQogKgogKiBDb3VsZCBiZSB1c2VkIHRvIHJlZ2lzdGVyIERpcmVjdERyYXcgZHJpdmVycywgaWYgd2UgaGF2ZSBtb3JlIHRoYW4KICogb25lLiBBbHNvIHVzZWQgdG8gZGVzdHJveSBhbnkgb2JqZWN0cyBsZWZ0IGF0IHVubG9hZCBpZiB0aGUKICogYXBwIGRpZG4ndCByZWxlYXNlIHRoZW0gcHJvcGVybHkoR290aGljIDIsIERpYWJsbyAyLCBNb3RvIHJhY2VyLCAuLi4pCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KQk9PTCBXSU5BUEkKRGxsTWFpbihISU5TVEFOQ0UgaEluc3RETEwsCiAgICAgICAgRFdPUkQgUmVhc29uLAogICAgICAgIHZvaWQgKmxwdikKewogICAgVFJBQ0UoIiglcCwleCwlcClcbiIsIGhJbnN0RExMLCBSZWFzb24sIGxwdik7CiAgICBpZiAoUmVhc29uID09IERMTF9QUk9DRVNTX0FUVEFDSCkKICAgIHsKICAgICAgICBjaGFyIGJ1ZmZlcltNQVhfUEFUSCsxMF07CiAgICAgICAgRFdPUkQgc2l6ZSA9IHNpemVvZihidWZmZXIpOwogICAgICAgIEhLRVkgaGtleSA9IDA7CiAgICAgICAgSEtFWSBhcHBrZXkgPSAwOwogICAgICAgIERXT1JEIGxlbjsKCiAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXERpcmVjdDNEICovCiAgICAgICBpZiAoIFJlZ09wZW5LZXlBKCBIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxXaW5lXFxEaXJlY3QzRCIsICZoa2V5ICkgKSBoa2V5ID0gMDsKCiAgICAgICBsZW4gPSBHZXRNb2R1bGVGaWxlTmFtZUEoIDAsIGJ1ZmZlciwgTUFYX1BBVEggKTsKICAgICAgIGlmIChsZW4gJiYgbGVuIDwgTUFYX1BBVEgpCiAgICAgICB7CiAgICAgICAgICAgIEhLRVkgdG1wa2V5OwogICAgICAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXEFwcERlZmF1bHRzXGFwcC5leGVcRGlyZWN0M0QgKi8KICAgICAgICAgICAgaWYgKCFSZWdPcGVuS2V5QSggSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcV2luZVxcQXBwRGVmYXVsdHMiLCAmdG1wa2V5ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnAsICphcHBuYW1lID0gYnVmZmVyOwogICAgICAgICAgICAgICAgaWYgKChwID0gc3RycmNociggYXBwbmFtZSwgJy8nICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBpZiAoKHAgPSBzdHJyY2hyKCBhcHBuYW1lLCAnXFwnICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBzdHJjYXQoIGFwcG5hbWUsICJcXERpcmVjdDNEIiApOwogICAgICAgICAgICAgICAgVFJBQ0UoImFwcG5hbWUgPSBbJXNdXG4iLCBhcHBuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChSZWdPcGVuS2V5QSggdG1wa2V5LCBhcHBuYW1lLCAmYXBwa2V5ICkpIGFwcGtleSA9IDA7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleSggdG1wa2V5ICk7CiAgICAgICAgICAgIH0KICAgICAgIH0KCiAgICAgICBpZiAoIDAgIT0gaGtleSB8fCAwICE9IGFwcGtleSApCiAgICAgICB7CiAgICAgICAgICAgIGlmICggIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJEaXJlY3REcmF3UmVuZGVyZXIiLCBidWZmZXIsIHNpemUpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoYnVmZmVyLCJnZGkiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGVmYXVsdGluZyB0byBHREkgc3VyZmFjZXNcbiIpOwogICAgICAgICAgICAgICAgICAgIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfR0RJOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChidWZmZXIsIm9wZW5nbCIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEZWZhdWx0aW5nIHRvIG9wZW5nbCBzdXJmYWNlc1xuIik7CiAgICAgICAgICAgICAgICAgICAgRGVmYXVsdFN1cmZhY2VUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIGRlZmF1bHQgc3VyZmFjZSB0eXBlLiBTdXBwb3J0ZWQgYXJlOlxuIGdkaSwgb3BlbmdsXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhoSW5zdERMTCk7CiAgICB9CiAgICBlbHNlIGlmIChSZWFzb24gPT0gRExMX1BST0NFU1NfREVUQUNIKQogICAgewogICAgICAgIGlmKCFsaXN0X2VtcHR5KCZnbG9iYWxfZGRyYXdfbGlzdCkpCiAgICAgICAgewogICAgICAgICAgICBzdHJ1Y3QgbGlzdCAqZW50cnksICplbnRyeTI7CiAgICAgICAgICAgIFdBUk4oIlRoZXJlIGFyZSBzdGlsbCBleGlzdGluZyBEaXJlY3REcmF3IGludGVyZmFjZXMuIFdpbmUgYnVnIG9yIGJ1Z2d5IGFwcGxpY2F0aW9uP1xuIik7CgogICAgICAgICAgICAvKiBXZSByZW1vdmUgZWxlbWV0cyBmcm9tIHRoaXMgbG9vcCAqLwogICAgICAgICAgICBMSVNUX0ZPUl9FQUNIX1NBRkUoZW50cnksIGVudHJ5MiwgJmdsb2JhbF9kZHJhd19saXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgZGVzYzsKICAgICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsICpkZHJhdyA9IExJU1RfRU5UUlkoZW50cnksIElEaXJlY3REcmF3SW1wbCwgZGRyYXdfbGlzdF9lbnRyeSk7CgogICAgICAgICAgICAgICAgV0FSTigiRERyYXcgJXAgaGFzIGEgcmVmY291bnQgb2YgJWRcbiIsIGRkcmF3LCBkZHJhdy0+cmVmNyArIGRkcmF3LT5yZWY0ICsgZGRyYXctPnJlZjMgKyBkZHJhdy0+cmVmMiArIGRkcmF3LT5yZWYxKTsKCiAgICAgICAgICAgICAgICAvKiBBZGQgcmVmZXJlbmNlcyB0byBlYWNoIGludGVyZmFjZSB0byBhdm9pZCBmcmVlaW5nIHRoZW0gdW5leHBlY3RhZGVseSAqLwogICAgICAgICAgICAgICAgSURpcmVjdERyYXdfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdykpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXcyX0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcyKSk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdzNfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzMpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3NF9BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NCkpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXc3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc3KSk7CgogICAgICAgICAgICAgICAgLyogRG9lcyBhIEQzRCBkZXZpY2UgZXhpc3Q/IERlc3Ryb3kgaXQKICAgICAgICAgICAgICAgICAgICAqIFRPRE86IERlc3Ryb3kgYWxsIFZlcnRleCBidWZmZXJzLCBMaWdodHMsIE1hdGVyaWFscwogICAgICAgICAgICAgICAgICAgICogYW5kIGV4ZWN0dXJlIGJ1ZmZlcnMgdG9vCiAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmKGRkcmF3LT5kM2RkZXZpY2UpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiRERyYXcgJXAgaGFzIGQzZGRldmljZSAlcCBhdHRhY2hlZFxuIiwgZGRyYXcsIGRkcmF3LT5kM2RkZXZpY2UpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3QzRERldmljZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdy0+ZDNkZGV2aWNlLCBJRGlyZWN0M0REZXZpY2U3KSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIFRyeSB0byByZWxlYXNlIHRoZSBvYmplY3RzCiAgICAgICAgICAgICAgICAgICAgKiBEbyBhbiBFbnVtU3VyZmFjZXMgdG8gZmluZCBhbnkgaGFuZ2luZyBzdXJmYWNlcwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBtZW1zZXQoJmRlc2MsIDAsIHNpemVvZihkZXNjKSk7CiAgICAgICAgICAgICAgICBkZXNjLmR3U2l6ZSA9IHNpemVvZihkZXNjKTsKICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaSA8PSAxOyBpKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaHIgPSBJRGlyZWN0RHJhdzdfRW51bVN1cmZhY2VzKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERFTlVNU1VSRkFDRVNfQUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBkZHJhdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3Ryb3lDYWxsYmFjayk7CiAgICAgICAgICAgICAgICAgICAgaWYoaHIgIT0gRDNEX09LKQogICAgICAgICAgICAgICAgICAgICAgICBFUlIoIiglcCkgRW51bVN1cmZhY2VzIGZhaWxlZCwgcHJlcGFyZSBmb3IgdHJvdWJsZVxuIiwgZGRyYXcpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIENoZWNrIHRoZSBzdXJmYWNlIGNvdW50ICovCiAgICAgICAgICAgICAgICBpZihkZHJhdy0+c3VyZmFjZXMgPiAwKQogICAgICAgICAgICAgICAgICAgIEVSUigiRERyYXcgJXAgc3RpbGwgaGFzICVkIHN1cmZhY2VzIGF0dGFjaGVkXG4iLCBkZHJhdywgZGRyYXctPnN1cmZhY2VzKTsKCiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIGFsbCBoYW5naW5nIHJlZmVyZW5jZXMgdG8gZGVzdHJveSB0aGUgb2JqZWN0cy4gVGhpcwogICAgICAgICAgICAgICAgICAgICogcmVzdG9yZXMgdGhlIHNjcmVlbiBtb2RlIHRvbwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhd19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdykpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3Ml9SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzIpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzNfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXczKSkpOwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXc0X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NCkpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3N19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzcpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0K