LyoKICogMkQgU3VyZmFjZSBpbXBsZW1lbnRhdGlvbiB3aXRob3V0IE9wZW5HTAogKgogKiBDb3B5cmlnaHQgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OC0yMDAwIExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwOCBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CgovKiBVc2UgdGhlIGQzZF9zdXJmYWNlIGRlYnVnIGNoYW5uZWwgdG8gaGF2ZSBvbmUgY2hhbm5lbCBmb3IgYWxsIHN1cmZhY2VzICovCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zdXJmYWNlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlJlbGVhc2UsIEdESSB2ZXJzaW9uCiAqCiAqIEluIGdlbmVyYWwgYSBub3JtYWwgQ09NIFJlbGVhc2UgbWV0aG9kLCBidXQgdGhlIEdESSB2ZXJzaW9uIGRvZXNuJ3QgaGF2ZQogKiB0byBkZXN0cm95IGFsbCB0aGUgR0wgdGhpbmdzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovClVMT05HIFdJTkFQSSBJV2luZUdESVN1cmZhY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZiArIDEpOwogICAgaWYgKHJlZiA9PSAwKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBjbGVhbmluZyB1cFxuIiwgVGhpcyk7CgogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQyAqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgSVdpbmVEM0RTdXJmYWNlX1NldE1lbShpZmFjZSwgTlVMTCk7CgogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBhbGV0dGU5KTsKCiAgICAgICAgSVdpbmVEM0RSZXNvdXJjZUltcGxfQ2xlYW5VcCgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKCiAgICAgICAgaWYoVGhpcy0+b3ZlcmxheV9kZXN0KSB7CiAgICAgICAgICAgIGxpc3RfcmVtb3ZlKCZUaGlzLT5vdmVybGF5X2VudHJ5KTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCIoJXApIFJlbGVhc2VkXG4iLCBUaGlzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpQcmVMb2FkLCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGNhbGwgaXMgdW5zdXBwb3J0ZWQgb24gR0RJIHN1cmZhY2VzLCBpZiBpdCdzIGNhbGxlZCBzb21ldGhpbmcgd2VudAogKiB3cm9uZyBpbiB0aGUgcGFyZW50IGxpYnJhcnkuIFdyaXRlIGFuIGluZm9ybWF0aXZlIHdhcm5pbmcKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9QcmVMb2FkKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIEVSUigiKCVwKTogUHJlTG9hZCBpcyBub3Qgc3VwcG9ydGVkIG9uIFgxMSBzdXJmYWNlcyFcbiIsIGlmYWNlKTsKICAgIEVSUigiKCVwKTogTW9zdCBsaWtlbHkgdGhlIHBhcmVudCBsaWJyYXJ5IGRpZCBzb21ldGhpbmcgd3JvbmcuXG4iLCBpZmFjZSk7CiAgICBFUlIoIiglcCk6IFBsZWFzZSByZXBvcnQgdG8gd2luZS1kZXZlbFxuIiwgaWZhY2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpVbkxvYWQsIEdESSB2ZXJzaW9uCiAqCiAqIFRoaXMgY2FsbCBpcyB1bnN1cHBvcnRlZCBvbiBHREkgc3VyZmFjZXMsIGlmIGl0J3MgY2FsbGVkIHNvbWV0aGluZyB3ZW50CiAqIHdyb25nIGluIHRoZSBwYXJlbnQgbGlicmFyeS4gV3JpdGUgYW4gaW5mb3JtYXRpdmUgd2FybmluZy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9VbkxvYWQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkKewogICAgRVJSKCIoJXApOiBVbkxvYWQgaXMgbm90IHN1cHBvcnRlZCBvbiBYMTEgc3VyZmFjZXMhXG4iLCBpZmFjZSk7CiAgICBFUlIoIiglcCk6IE1vc3QgbGlrZWx5IHRoZSBwYXJlbnQgbGlicmFyeSBkaWQgc29tZXRoaW5nIHdyb25nLlxuIiwgaWZhY2UpOwogICAgRVJSKCIoJXApOiBQbGVhc2UgcmVwb3J0IHRvIHdpbmUtZGV2ZWxcbiIsIGlmYWNlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6TG9ja1JlY3QsIEdESSB2ZXJzaW9uCiAqCiAqIExvY2tzIHRoZSBzdXJmYWNlIGFuZCByZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgc3VyZmFjZSBtZW1vcnkKICoKICogUGFyYW1zOgogKiAgcExvY2tlZFJlY3Q6IEFkZHJlc3MgdG8gcmV0dXJuIHRoZSBsb2NraW5nIGluZm8gYXQKICogIHBSZWN0OiBSZWN0YW5nbGUgdG8gbG9jawogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBvbiBlcnJvcnMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgUkVDVCogcFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIEFscmVhZHkgbG9ja2VkPyAqLwogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFN1cmZhY2UgYWxyZWFkeSBsb2NrZWRcbiIsIFRoaXMpOwogICAgICAgIC8qIFdoYXQgc2hvdWxkIEkgcmV0dXJuIGhlcmU/ICovCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19MT0NLRUQ7CgogICAgaWYoIVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIC8qIFRoaXMgaGFwcGVucyBvbiBnZGkgc3VyZmFjZXMgaWYgdGhlIGFwcGxpY2F0aW9uIHNldCBhIHVzZXIgcG9pbnRlciBhbmQgcmVzZXRzIGl0LgogICAgICAgICAqIFJlY3JlYXRlIHRoZSBESUIgc2VjdGlvbgogICAgICAgICAqLwogICAgICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0NyZWF0ZURJQlNlY3Rpb24oaWZhY2UpOwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IFRoaXMtPmRpYi5iaXRtYXBfZGF0YTsKICAgIH0KCiAgICByZXR1cm4gSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfTG9ja1JlY3QoaWZhY2UsIHBMb2NrZWRSZWN0LCBwUmVjdCwgRmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpVbmxvY2tSZWN0LCBHREkgdmVyc2lvbgogKgogKiBVbmxvY2tzIGEgc3VyZmFjZS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IGRvIG11Y2gsIGV4Y2VwdCB1cGRhdGluZwogKiB0aGUgd2luZG93IGlmIHRoZSBmcm9udCBidWZmZXIgaXMgdW5sb2NrZWQKICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBvbiBmYWlsdXJlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfVW5sb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpCiAgICB7CiAgICAgICAgV0FSTigidHJ5aW5nIHRvIFVubG9jayBhbiB1bmxvY2tlZCBzdXJmQCVwXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBDYW4gYmUgdXNlZnVsIGZvciBkZWJ1Z2dpbmcgKi8KI2lmIDAKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICAgICAgY2hhciBidWZmZXJbNDA5Nl07CiAgICAgICAgICAgICsrZ2VuOwogICAgICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLCAiL3RtcC9zdXJmYWNlJXBfdHlwZSV1X2xldmVsJXVfJXUucHBtIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGdlbik7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChpZmFjZSwgYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkZWJ1Z2dpbmcgY3Jhc2ggY29kZQogICAgICAgICAgICBpZiAoZ2VuID09IDI1MCkgewogICAgICAgICAgICAgIHZvaWQqKiB0ZXN0ID0gTlVMTDsKICAgICAgICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKi8KICAgICAgICB9CiNlbmRpZgoKICAgIC8qIFRlbGwgdGhlIHN3YXBjaGFpbiB0byB1cGRhdGUgdGhlIHNjcmVlbiAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopICZzd2FwY2hhaW4pOwogICAgaWYoc3dhcGNoYWluKSB7CiAgICAgICAgeDExX2NvcHlfdG9fc2NyZWVuKHN3YXBjaGFpbiwgJlRoaXMtPmxvY2tlZFJlY3QpOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0xPQ0tFRDsKICAgIG1lbXNldCgmVGhpcy0+bG9ja2VkUmVjdCwgMCwgc2l6ZW9mKFJFQ1QpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpGbGlwLCBHREkgdmVyc2lvbgogKgogKiBGbGlwcyAyIGZsaXBwaW5nIGVuYWJsZWQgc3VyZmFjZXMuIERldGVybWluaW5nIHRoZSAyIHRhcmdldHMgaXMgZG9uZSBieQogKiB0aGUgcGFyZW50IGxpYnJhcnkuIFRoaXMgaW1wbGVtZW50YXRpb24gY2hhbmdlcyB0aGUgZGF0YSBwb2ludGVycyBvZiB0aGUKICogc3VyZmFjZXMgYW5kIGNvcGllcyB0aGUgbmV3IGZyb250IGJ1ZmZlciBjb250ZW50IHRvIHRoZSBzY3JlZW4KICoKICogUGFyYW1zOgogKiAgb3ZlcnJpZGU6IEZsaXBwaW5nIHRhcmdldChlLmcuIGJhY2sgYnVmZmVyKQogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfRmxpcChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpvdmVycmlkZSwKICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSAmc3dhcGNoYWluKTsKICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICBFUlIoIkZsaXBwZWQgc3VyZmFjZSBpcyBub3Qgb24gYSBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfTk9URkxJUFBBQkxFOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fUHJlc2VudCgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluLCBOVUxMLCBOVUxMLCAwLCBOVUxMLCAwKTsKICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkxvYWRUZXh0dXJlLCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGlzIG11dHVhbGx5IHVuc3VwcG9ydGVkIGJ5IEdESSBzdXJmYWNlcwogKgogKiBSZXR1cm5zOgogKiAgRDNERVJSX0lOVkFMSURDQUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBCT09MIHNyZ2JfbW9kZSkKewogICAgRVJSKCJVbnN1cHBvcnRlZCBvbiBYMTEgc3VyZmFjZXNcbiIpOwogICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlNhdmVTbmFwc2hvdCwgR0RJIHZlcnNpb24KICoKICogVGhpcyBtZXRob2Qgd3JpdGVzIHRoZSBzdXJmYWNlJ3MgY29udGVudHMgdG8gdGhlIGluIHRnYSBmb3JtYXQgdG8gdGhlCiAqIGZpbGUgc3BlY2lmaWVkIGluIGZpbGVuYW1lLgogKgogKiBQYXJhbXM6CiAqICBmaWxlbmFtZTogRmlsZSB0byB3cml0ZSB0bwogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBpZiB0aGUgZmlsZSBjb3VsZG4ndCBiZSBvcGVuZWQKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBpbnQgZ2V0X3NoaWZ0KERXT1JEIGNvbG9yX21hc2spIHsKICAgIGludCBzaGlmdCA9IDA7CiAgICB3aGlsZSAoY29sb3JfbWFzayA+IDB4RkYpIHsKICAgICAgICBjb2xvcl9tYXNrID4+PSAxOwogICAgICAgIHNoaWZ0ICs9IDE7CiAgICB9CiAgICB3aGlsZSAoKGNvbG9yX21hc2sgJiAweDgwKSA9PSAwKSB7CiAgICAgICAgY29sb3JfbWFzayA8PD0gMTsKICAgICAgICBzaGlmdCAtPSAxOwogICAgfQogICAgcmV0dXJuIHNoaWZ0Owp9CgoKSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKY29uc3QgY2hhciogZmlsZW5hbWUpCnsKICAgIEZJTEUqIGYgPSBOVUxMOwogICAgVUlOVCB5ID0gMCwgeCA9IDA7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBjaGFyICpvdXRwdXQgPSBOVUxMOwogICAgc3RhdGljIGludCBzaXplID0gMDsKICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0LCBOVUxMLCBOVUxMKTsKCiAgICBpZiAoVGhpcy0+cG93MldpZHRoID4gc2l6ZSkgewogICAgICAgIG91dHB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5wb3cyV2lkdGggKiAzKTsKICAgICAgICBzaXplID0gVGhpcy0+cG93MldpZHRoOwogICAgfQoKCiAgICBmID0gZm9wZW4oZmlsZW5hbWUsICJ3KyIpOwogICAgaWYgKE5VTEwgPT0gZikgewogICAgICAgIEVSUigib3BlbmluZyBvZiAlcyBmYWlsZWQgd2l0aFxuIiwgZmlsZW5hbWUpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgZnByaW50ZihmLCAiUDZcbiVkICVkXG4yNTVcbiIsIFRoaXMtPnBvdzJXaWR0aCwgVGhpcy0+cG93MkhlaWdodCk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSB7CiAgICAgICAgdW5zaWduZWQgY2hhciB0YWJsZVsyNTZdWzNdOwogICAgICAgIGludCBpOwoKICAgICAgICBpZiAoVGhpcy0+cGFsZXR0ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIGZjbG9zZShmKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICB0YWJsZVtpXVswXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVCbHVlOwogICAgICAgIH0KICAgICAgICBmb3IgKHkgPSAwOyB5IDwgVGhpcy0+cG93MkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnNyYyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArICh5ICogMSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSkpOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgVGhpcy0+cG93MldpZHRoOyB4KyspIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgY29sb3IgPSAqc3JjOwogICAgICAgICAgICAgICAgc3JjICs9IDE7CgogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMF0gPSB0YWJsZVtjb2xvcl1bMF07CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAxXSA9IHRhYmxlW2NvbG9yXVsxXTsKICAgICAgICAgICAgICAgIG91dHB1dFszICogeCArIDJdID0gdGFibGVbY29sb3JdWzJdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ3cml0ZShvdXRwdXQsIDMgKiBUaGlzLT5wb3cyV2lkdGgsIDEsIGYpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaW50IHJlZF9zaGlmdCwgZ3JlZW5fc2hpZnQsIGJsdWVfc2hpZnQsIHBpeF93aWR0aCwgYWxwaGFfc2hpZnQ7CgogICAgICAgIHBpeF93aWR0aCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CgogICAgICAgIHJlZF9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+cmVkTWFzayk7CiAgICAgICAgZ3JlZW5fc2hpZnQgPSBnZXRfc2hpZnQoZm9ybWF0RW50cnktPmdyZWVuTWFzayk7CiAgICAgICAgYmx1ZV9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+Ymx1ZU1hc2spOwogICAgICAgIGFscGhhX3NoaWZ0ID0gZ2V0X3NoaWZ0KGZvcm1hdEVudHJ5LT5hbHBoYU1hc2spOwoKICAgICAgICBmb3IgKHkgPSAwOyB5IDwgVGhpcy0+cG93MkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnNyYyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArICh5ICogMSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSkpOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgVGhpcy0+cG93MldpZHRoOyB4KyspIHsJICAgIAogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGNvbG9yOwogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGNvbXA7CiAgICAgICAgICAgICAgICBpbnQgaTsKCiAgICAgICAgICAgICAgICBjb2xvciA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGl4X3dpZHRoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciB8PSBzcmNbaV0gPDwgKDggKiBpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNyYyArPSAxICogcGl4X3dpZHRoOwoKICAgICAgICAgICAgICAgIGNvbXAgPSBjb2xvciAmIGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMF0gPSByZWRfc2hpZnQgPiAwID8gY29tcCA+PiByZWRfc2hpZnQgOiBjb21wIDw8IC1yZWRfc2hpZnQ7CiAgICAgICAgICAgICAgICBjb21wID0gY29sb3IgJiBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMV0gPSBncmVlbl9zaGlmdCA+IDAgPyBjb21wID4+IGdyZWVuX3NoaWZ0IDogY29tcCA8PCAtZ3JlZW5fc2hpZnQ7CiAgICAgICAgICAgICAgICBjb21wID0gY29sb3IgJiBmb3JtYXRFbnRyeS0+YWxwaGFNYXNrOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMl0gPSBhbHBoYV9zaGlmdCA+IDAgPyBjb21wID4+IGFscGhhX3NoaWZ0IDogY29tcCA8PCAtYWxwaGFfc2hpZnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZndyaXRlKG91dHB1dCwgMyAqIFRoaXMtPnBvdzJXaWR0aCwgMSwgZik7CiAgICAgICAgfQogICAgfQogICAgZmNsb3NlKGYpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lR0RJU3VyZmFjZUltcGxfR2V0REMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDICpwSERDKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCBsb2NrOwogICAgSFJFU1VMVCBocjsKICAgIFJHQlFVQUQgY29sWzI1Nl07CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxwSERDKTsKCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpIHsKICAgICAgICBFUlIoIk5vdCBzdXBwb3J0ZWQgb24gc3VyZmFjZXMgd2l0aCBhbiBhcHBsaWNhdGlvbi1wcm92aWRlZCBzdXJmYWNlc1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT0RDOwogICAgfQoKICAgIC8qIEdpdmUgbW9yZSBkZXRhaWxlZCBpbmZvIGZvciBkZHJhdyAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkKICAgICAgICByZXR1cm4gV0lORURERVJSX0RDQUxSRUFEWUNSRUFURUQ7CgogICAgLyogQ2FuJ3QgR2V0REMgaWYgdGhlIHN1cmZhY2UgaXMgbG9ja2VkICovCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtc2V0KCZsb2NrLCAwLCBzaXplb2YobG9jaykpOyAvKiBUbyBiZSBzdXJlICovCgogICAgLyogU2hvdWxkIGhhdmUgYSBESUIgc2VjdGlvbiBhbHJlYWR5ICovCgogICAgLyogTG9jayB0aGUgc3VyZmFjZSAqLwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIklXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdCBmYWlsZWQgd2l0aCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICAvKiBrZWVwIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fAogICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCkgewogICAgICAgIHVuc2lnbmVkIGludCBuOwogICAgICAgIFBBTEVUVEVFTlRSWSAqcGFsID0gTlVMTDsKCiAgICAgICAgaWYoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBwYWwgPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKmRkc19wcmltYXJ5OwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbjsKICAgICAgICAgICAgc3dhcGNoYWluID0gKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPnN3YXBjaGFpbnNbMF07CiAgICAgICAgICAgIGRkc19wcmltYXJ5ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilzd2FwY2hhaW4tPmZyb250QnVmZmVyOwogICAgICAgICAgICBpZiAoZGRzX3ByaW1hcnkgJiYgZGRzX3ByaW1hcnktPnBhbGV0dGUpCiAgICAgICAgICAgICAgICBwYWwgPSBkZHNfcHJpbWFyeS0+cGFsZXR0ZS0+cGFsZW50czsKICAgICAgICB9CgogICAgICAgIGlmIChwYWwpIHsKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IHBhbFtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IHBhbFtuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gcGFsW25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgU2V0RElCQ29sb3JUYWJsZShUaGlzLT5oREMsIDAsIDI1NiwgY29sKTsKICAgICAgICB9CiAgICB9CgogICAgKnBIREMgPSBUaGlzLT5oREM7CiAgICBUUkFDRSgicmV0dXJuaW5nICVwXG4iLCpwSERDKTsKICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lR0RJU3VyZmFjZUltcGxfUmVsZWFzZURDKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEhEQyBoREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsaERDKTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RDSU5VU0UpKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIGlmIChUaGlzLT5oREMgIT1oREMpIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiB0cmllcyB0byByZWxlYXNlIGFuIGludmFsaWQgREMoJXApLCBzdXJmYWNlIGRjIGlzICVwXG4iLCBoREMsIFRoaXMtPmhEQyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogd2UgbG9ja2VkIGZpcnN0LCBzbyB1bmxvY2sgbm93ICovCiAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChpZmFjZSk7CgogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lR0RJU3VyZmFjZUltcGxfUmVhbGl6ZVBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgUkdCUVVBRCBjb2xbMjU2XTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKnBhbCA9IFRoaXMtPnBhbGV0dGU7CiAgICB1bnNpZ25lZCBpbnQgbjsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmICghcGFsKSByZXR1cm4gV0lORUQzRF9PSzsKCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICBUUkFDRSgiKCVwKTogVXBkYXRpbmcgdGhlIGhkYydzIHBhbGV0dGVcbiIsIFRoaXMpOwogICAgICAgIGZvciAobj0wOyBuPDI1NjsgbisrKSB7CiAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IHBhbC0+cGFsZW50c1tuXS5wZVJlZDsKICAgICAgICAgICAgY29sW25dLnJnYkdyZWVuID0gcGFsLT5wYWxlbnRzW25dLnBlR3JlZW47CiAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IHBhbC0+cGFsZW50c1tuXS5wZUJsdWU7CiAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgfQogICAgICAgIFNldERJQkNvbG9yVGFibGUoVGhpcy0+aERDLCAwLCAyNTYsIGNvbCk7CiAgICB9CgogICAgLyogVXBkYXRlIHRoZSBpbWFnZSBiZWNhdXNlIG9mIHRoZSBwYWxldHRlIGNoYW5nZS4gU29tZSBnYW1lcyBsaWtlIGUuZyBSZWQgQWxlcnQKICAgICAgIGNhbGwgU2V0RW50cmllcyBhIGxvdCB0byBpbXBsZW1lbnQgZmFkaW5nLiAqLwogICAgLyogVGVsbCB0aGUgc3dhcGNoYWluIHRvIHVwZGF0ZSB0aGUgc2NyZWVuICovCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikgJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4pIHsKICAgICAgICB4MTFfY29weV90b19zY3JlZW4oc3dhcGNoYWluLCAmVGhpcy0+bG9ja2VkUmVjdCk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6UHJpdmF0ZVNldHVwLCBHREkgdmVyc2lvbgogKgogKiBJbml0aWFsaXplcyB0aGUgR0RJIHN1cmZhY2UsIGFrYSBjcmVhdGVzIHRoZSBESUIgc2VjdGlvbiB3ZSByZW5kZXIgdG8KICogVGhlIERJQiBzZWN0aW9uIGNyZWF0aW9uIGlzIGRvbmUgYnkgY2FsbGluZyBHZXREQywgd2hpY2ggd2lsbCBjcmVhdGUgdGhlCiAqIHNlY3Rpb24gYW5kIHJlbGVhc2luZyB0aGUgZGMgdG8gYWxsb3cgdGhlIGFwcCB0byB1c2UgaXQuIFRoZSBkaWIgc2VjdGlvbgogKiB3aWxsIHN0YXkgdW50aWwgdGhlIHN1cmZhY2UgaXMgcmVsZWFzZWQKICoKICogR0RJIHN1cmZhY2VzIGRvIG5vdCBuZWVkIHRvIGJlIGEgcG93ZXIgb2YgMiBpbiBzaXplLCBzbyB0aGUgcG93MiBzaXplcwogKiBhcmUgc2V0IHRvIHRoZSByZWFsIHNpemVzIHRvIHNhdmUgbWVtb3J5LiBUaGUgTk9OUE9XMiBmbGFnIGlzIHVuc2V0IHRvCiAqIGF2b2lkIGNvbmZ1c2lvbiBpbiB0aGUgc2hhcmVkIHN1cmZhY2UgY29kZS4KICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgVGhlIHJldHVybiB2YWx1ZXMgb2YgY2FsbGVkIG1ldGhvZHMgb24gZmFpbHVyZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKQogICAgewogICAgICAgIEVSUigiKCVwKSBPdmVybGF5cyBub3QgeWV0IHN1cHBvcnRlZCBieSBHREkgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLyogU3lzbWVtIHRleHR1cmVzIGhhdmUgbWVtb3J5IGFscmVhZHkgYWxsb2NhdGVkIC0KICAgICAqIHJlbGVhc2UgaXQsIHRoaXMgYXZvaWRzIGFuIHVubmVjZXNzYXJ5IG1lbWNweQogICAgICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5KTsKICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKCiAgICAvKiBXZSBkb24ndCBtaW5kIHRoZSBub25wb3cyIHN0dWZmIGluIEdESSAqLwogICAgVGhpcy0+cG93MldpZHRoID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBUaGlzLT5wb3cySGVpZ2h0ID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwoKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0NyZWF0ZURJQlNlY3Rpb24oaWZhY2UpOwogICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUdESVN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgVUlOVCB0ZXh0dXJlTmFtZSwgaW50IHRhcmdldCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgLyogSWdub3JlIDAgdGV4dHVyZU5hbWUgYW5kIHRhcmdldC4gRDNEIHRleHR1cmVzIGNhbiBiZSBjcmVhdGVkIHdpdGggZ2RpIHN1cmZhY2VzIGFzIHBsYWluCiAgICAgKiBjb250YWluZXJzLCBidXQgdGhleSdyZSB1c2VsZXNzIHVudGlsIHRoZSBhcHAgY3JlYXRlcyBhIGQzZCBkZXZpY2UgZnJvbSBhIGQzZCBwb2ludCBvZgogICAgICogdmlldywgaXQncyBub3QgYW4gaW1wbGVtZW50YXRpb24gbGltaXRhdGlvbi4gVGhpcyBhdm9pZHMgZmFsc2Ugd2FybmluZ3Mgd2hlbiB0aGUgdGV4dHVyZQogICAgICogaXMgZGVzdHJveWVkIGFuZCBzZXRzIHRoZSBkZXNjcmlwdGlvbiBiYWNrIHRvIDAvMAogICAgICovCiAgICBpZih0ZXh0dXJlTmFtZSAhPSAwIHx8IHRhcmdldCAhPSAwKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBTaG91bGQgbm90IGJlIGNhbGxlZCBvbiBhIEdESSBzdXJmYWNlLiB0ZXh0dXJlTmFtZSAldSwgdGFyZ2V0ICVpXG4iLCBUaGlzLCB0ZXh0dXJlTmFtZSwgdGFyZ2V0KTsKICAgICAgICBEZWJ1Z0JyZWFrKCk7CiAgICB9Cn0KCnZvaWQgV0lOQVBJIElXaW5lR0RJU3VyZmFjZUltcGxfR2V0R2xEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIGdsRGVzY3JpcHRvciAqKmdsRGVzY3JpcHRpb24pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBTaG91bGQgbm90IGJlIGNhbGxlZCBvbiBhIEdESSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICpnbERlc2NyaXB0aW9uID0gTlVMTDsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9BZGREaXJ0eVJlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OU1QgUkVDVCogcERpcnR5UmVjdCkgewogICAgLyogR0RJIHN1cmZhY2UgZGF0YSBjYW4gb25seSBiZSBpbiBvbmUgbG9jYXRpb24sIHRoZSBzeXN0ZW0gbWVtb3J5IGRpYiBzZWN0aW9uLiBTbyB0aGV5IGFyZQogICAgICogYWx3YXlzIGNsZWFuIGJ5IGRlZmluaXRpb24uCiAgICAgKi8KICAgIFRSQUNFKCJObyBkaXJ0aWZpY2F0aW9uIGluIEdESSBzdXJmYWNlc1xuIik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9TZXRNZW0oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgdm9pZCAqTWVtKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgLyogUmVuZGVyIHRhcmdldHMgZGVwZW5kIG9uIHRoZWlyIGhkYywgYW5kIHdlIGNhbid0IGNyZWF0ZSBhbiBoZGMgb24gYSB1c2VyIHBvaW50ZXIgKi8KICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIEVSUigiTm90IHN1cHBvcnRlZCBvbiByZW5kZXIgdGFyZ2V0c1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfTE9DS0VEIHwgU0ZMQUdfRENJTlVTRSkpIHsKICAgICAgICBXQVJOKCJTdXJmYWNlIGlzIGxvY2tlZCBvciB0aGUgSERDIGlzIGluIHVzZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoTWVtICYmIE1lbSAhPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICB2b2lkICpyZWxlYXNlID0gTlVMTDsKCiAgICAgICAgLyogRG8gSSBoYXZlIHRvIGNvcHkgdGhlIG9sZCBzdXJmYWNlIGNvbnRlbnQ/ICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQy4gTm8gbmVlZCB0byBob2xkIHRoZSBjcml0aWNhbCBzZWN0aW9uIGZvciB0aGUgdXBkYXRlCiAgICAgICAgICAgICogVGhyZWFkIGJlY2F1c2UgdGhpcyB0aHJlYWQgcnVucyBvbmx5IG9uIGZyb250IGJ1ZmZlcnMsIGJ1dCB0aGlzIG1ldGhvZAogICAgICAgICAgICAqIGZhaWxzIGZvciByZW5kZXIgdGFyZ2V0cyBpbiB0aGUgY2hlY2sgYWJvdmUuCiAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPmhEQyA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESUJTRUNUSU9OOwogICAgICAgIH0gZWxzZSBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikpIHsKICAgICAgICAgICAgcmVsZWFzZSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTWVtOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX1VTRVJQVFIgfCBTRkxBR19JTlNZU01FTTsKCiAgICAgICAgLyogTm93IGZyZWUgdGhlIG9sZCBtZW1vcnkgaWYgYW55ICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVsZWFzZSk7CiAgICB9IGVsc2UgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgLyogTG9ja1JlY3QgYW5kIEdldERDIHdpbGwgcmUtY3JlYXRlIHRoZSBkaWIgc2VjdGlvbiBhbmQgYWxsb2NhdGVkIG1lbW9yeSAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX1VTRVJQVFI7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9Nb2RpZnlMb2NhdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBmbGFnLCBCT09MIHBlcnNpc3RlbnQpIHsKICAgIFRSQUNFKCIoJXApLT4oJXMsICVzKVxuIiwgaWZhY2UsCiAgICAgICAgICBmbGFnID09IFNGTEFHX0lOU1lTTUVNID8gIlNGTEFHX0lOU1lTTUVNIiA6IGZsYWcgPT0gU0ZMQUdfSU5EUkFXQUJMRSA/ICJTRkxBR19JTkRSQVdBQkxFIiA6ICJTRkxBR19JTlRFWFRVUkUiLAogICAgICAgICAgcGVyc2lzdGVudCA/ICJUUlVFIiA6ICJGQUxTRSIpOwogICAgLyogR0RJIHN1cmZhY2VzIGNhbiBiZSBpbiBzeXN0ZW0gbWVtb3J5IG9ubHkgKi8KICAgIGlmKGZsYWcgIT0gU0ZMQUdfSU5TWVNNRU0pIHsKICAgICAgICBFUlIoIkdESSBTdXJmYWNlIHJlcXVlc3RlZCBpbiBnbCAlcyBtZW1vcnlcbiIsIGZsYWcgPT0gU0ZMQUdfSU5EUkFXQUJMRSA/ICJkcmF3YWJsZSIgOiAidGV4dHVyZSIpOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkTG9jYXRpb24oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgZmxhZywgY29uc3QgUkVDVCAqcmVjdCkgewogICAgaWYoZmxhZyAhPSBTRkxBR19JTlNZU01FTSkgewogICAgICAgIEVSUigiR0RJIFN1cmZhY2UgcmVxdWVzdGVkIHRvIGJlIGNvcGllZCB0byBnbCAlc1xuIiwgZmxhZyA9PSBTRkxBR19JTlRFWFRVUkUgPyAidGV4dHVyZSIgOiAiZHJhd2FibGUiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgcmVxdWVzdGVkIGluIHN1cmZhY2UgbWVtb3J5XG4iKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgV0lORUQzRFNVUkZUWVBFIFdJTkFQSSBJV2luZUdESVN1cmZhY2VJbXBsX0dldEltcGxUeXBlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIHJldHVybiBTVVJGQUNFX0dESTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lR0RJU3VyZmFjZUltcGxfRHJhd092ZXJsYXkoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgRklYTUUoIkdESSBzdXJmYWNlcyBjYW4ndCBkcmF3IG92ZXJsYXlzIHlldFxuIik7CiAgICByZXR1cm4gRV9GQUlMOwp9CgovKiBGSVhNRTogVGhpcyB2dGFibGUgc2hvdWxkIG5vdCB1c2UgYW55IElXaW5lRDNEU3VyZmFjZSogaW1wbGVtZW50YXRpb24gZnVuY3Rpb25zLAogKiBvbmx5IElXaW5lRDNEQmFzZVN1cmZhY2UgYW5kIElXaW5lR0RJU3VyZmFjZSBvbmVzLgogKi8KY29uc3QgSVdpbmVEM0RTdXJmYWNlVnRibCBJV2luZUdESVN1cmZhY2VfVnRibCA9CnsKICAgIC8qIElVbmtub3duICovCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0FkZFJlZiwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfUmVsZWFzZSwKICAgIC8qIElXaW5lRDNEUmVzb3VyY2UgKi8KICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFBhcmVudCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldERldmljZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRQcmlvcml0eSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFByaW9yaXR5LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9QcmVMb2FkLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9VbkxvYWQsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRUeXBlLAogICAgLyogSVdpbmVEM0RTdXJmYWNlICovCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRDb250YWluZXIsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXREZXNjLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2NrUmVjdCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfVW5sb2NrUmVjdCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfR2V0REMsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1JlbGVhc2VEQywKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfRmxpcCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0JsdCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cywKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9Jc0xvc3QsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9SZXN0b3JlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQmx0RmFzdCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFBhbGV0dGUsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRQYWxldHRlLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldENvbG9yS2V5LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGl0Y2gsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1NldE1lbSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlaT3JkZXIsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q2xpcHBlciwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldENsaXBwZXIsCiAgICAvKiBJbnRlcm5hbCB1c2U6ICovCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0FkZERpcnR5UmVjdCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfTG9hZFRleHR1cmUsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CaW5kVGV4dHVyZSwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9TZXRHbFRleHR1cmVEZXNjLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9HZXRHbERlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRGb3JtYXQsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1ByaXZhdGVTZXR1cCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfTW9kaWZ5TG9jYXRpb24sCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0xvYWRMb2NhdGlvbiwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfR2V0SW1wbFR5cGUsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0RyYXdPdmVybGF5Cn07Cg==