LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDItMjAwNSBKYXNvbiBFZG1lYWRlcwogKiBDb3B5cmlnaHQgMjAwMi0yMDAzIFJhcGhhZWwgSnVucXVlaXJhCiAqIENvcHlyaWdodCAyMDA0IENocmlzdGlhbiBDb3N0YQogKiBDb3B5cmlnaHQgMjAwNSBPbGl2ZXIgU3RpZWJlcgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Rfc3VyZmFjZSk7CiNkZWZpbmUgR0xJTkZPX0xPQ0FUSU9OICgoSVdpbmVEM0RJbXBsICopKCgoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSktPndpbmVEM0QpKS0+Z2xfaW5mbwoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVVua25vd24gcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcG9iaikKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICAvKiBXYXJuICxidXQgYmUgbmljZSBhYm91dCB0aGluZ3MgKi8KICAgIFRSQUNFKCIoJXApLT4oJXMsJXApXG4iLCBUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwogICAgaWYgKHJpaWQgPT0gTlVMTCkgewogICAgICAgIEVSUigiUHJvYmFibHkgRklYTUU6IENhbGxpbmcgcXVlcnkgaW50ZXJmYWNlIHdpdGggTlVMTCByaWlkXG4iKTsKICAgIH0KICAgIGlmIChJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lVbmtub3duKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RCYXNlKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RSZXNvdXJjZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEU3VyZmFjZSkpIHsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoKElVbmtub3duKilpZmFjZSk7CiAgICAgICAgKnBwb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgICpwcG9iaiA9IE5VTEw7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKVUxPTkcgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkUmVmKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlc291cmNlLnJlZik7CiAgICBUUkFDRSgiKCVwKSA6IEFkZFJlZiBpbmNyZWFzaW5nIGZyb20gJWxkXG4iLCBUaGlzLHJlZiAtIDEpOwogICAgcmV0dXJuIHJlZjsKfQoKVUxPTkcgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZXNvdXJjZS5yZWYpOwogICAgVFJBQ0UoIiglcCkgOiBSZWxlYXNpbmcgZnJvbSAlbGRcbiIsIFRoaXMsIHJlZiArIDEpOwogICAgaWYgKHJlZiA9PSAwKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBjbGVhbmluZyB1cFxuIiwgVGhpcyk7CiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgIT0gMCkgeyAvKiByZWxlYXNlIHRoZSBvcGVuR0wgdGV4dHVyZS4uICovCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIFRSQUNFKCJEZWxldGluZyB0ZXh0dXJlICVkXG4iLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgREMgKi8KICAgICAgICAgICAgU2VsZWN0T2JqZWN0KFRoaXMtPmhEQywgVGhpcy0+ZGliLmhvbGRiaXRtYXApOwogICAgICAgICAgICBEZWxldGVEQyhUaGlzLT5oREMpOwogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBESUIgc2VjdGlvbiAqLwogICAgICAgICAgICBEZWxldGVPYmplY3QoVGhpcy0+ZGliLkRJQnNlY3Rpb24pOwogICAgICAgICAgICBUaGlzLT5kaWIuYml0bWFwX2RhdGEgPSBOVUxMOwogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0RSZXNvdXJjZUltcGxfQ2xlYW5VcCgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKCiAgICAgICAgVFJBQ0UoIiglcCkgUmVsZWFzZWRcbiIsIFRoaXMpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwoKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEUmVzb3VyY2UgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXZpY2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0REZXZpY2UqKiBwcERldmljZSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldERldmljZSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCBwcERldmljZSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGR1VJRCByZWZndWlkLCBDT05TVCB2b2lkKiBwRGF0YSwgRFdPUkQgU2l6ZU9mRGF0YSwgRFdPUkQgRmxhZ3MpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9TZXRQcml2YXRlRGF0YSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCByZWZndWlkLCBwRGF0YSwgU2l6ZU9mRGF0YSwgRmxhZ3MpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgdm9pZCogcERhdGEsIERXT1JEKiBwU2l6ZU9mRGF0YSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBwU2l6ZU9mRGF0YSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfRnJlZVByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCByZWZndWlkKTsKfQoKRFdPUkQgICBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcmlvcml0eShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBQcmlvcml0eU5ldykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaW9yaXR5KChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIFByaW9yaXR5TmV3KTsKfQoKRFdPUkQgICBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcmlvcml0eShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCnZvaWQgICAgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUHJlTG9hZChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICAvKiBUT0RPOiByZS13cml0ZSB0aGUgd2F5IHRleHR1cmVzIGFuZCBtYW5hZ2VkLAogICAgKiAgdXNlIGEgJ29wZW5nbCBjb250ZXh0IG1hbmFnZXInIHRvIG1hbmFnZSBSZW5kZXJUYXJnZXQgc3VyZmFjZXMKICAgICoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiBUT0RPOiBjaGVjayBmb3IgbG9ja3MgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqYmFzZVRleHR1cmUgPSBOVUxMOwogICAgVFJBQ0UoIiglcClDaGVja2luZyB0byBzZWUgaWYgdGhlIGNvbnRhaW5lciBpcyBhIGJhc2UgdGV4dHVyZVxuIiwgVGhpcyk7CiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb25hdGluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChiYXNlVGV4dHVyZSk7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKGJhc2VUZXh0dXJlKTsKICAgIH0gZWxzZSB7CiAgICBUUkFDRSgiKCVwKSA6IEFib3V0IHRvIGxvYWQgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICBFTlRFUl9HTCgpOwojaWYgMCAvKiBUT0RPOiBjb250ZXh0IG1hbmFnZXIgc3VwcG9ydCAqLwogICAgIElXaW5lRDNEQ29udGV4dE1hbmFnZXJfUHVzaFN0YXRlKFRoaXMtPmNvbnRleHRNYW5hZ2VyLCBHTF9URVhUVVJFXzJELCBFTkFCTEVELCBOT1cgLyogbWFrZSBzdXJlIHRoZSBzdGF0ZSBpcyBhcHBsaWVkIG5vdyAqLyk7CiNlbmRpZgogICAgZ2xFbmFibGUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOy8qIG1ha2Ugc3VyZSB0ZXh0dXJlIHN1cHBvcnQgaXMgZW5hYmxlZCBpbiB0aGlzIGNvbnRleHQgKi8KICAgIGlmIChUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsID09IDAgJiYgIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPT0gMCkgewogICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlcyIpOwogICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgZ2l2ZW4gbmFtZSAlZFxuIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICBnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CiAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZFRleHR1cmUoaWZhY2UpOwogICAgICAgICAgLyogVGhpcyBpcyB3aGVyZSB3ZSBzaG91bGQgYmUgcmVkdWNpbmcgdGhlIGFtb3VudCBvZiBHTE1lbW9yeVVzZWQgKi8KICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwgPT0gMCkgewogICAgICAgICAgZ2xCaW5kVGV4dHVyZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRUZXh0dXJlKGlmYWNlKTsKICAgICAgICB9IGVsc2UgIGlmIChUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lICE9IDApIHsgLyogTk9URTogdGhlIGxldmVsIDAgc3VyZmFjZSBvZiBhIG1wbWFwcGVkIHRleHR1cmUgbXVzdCBiZSBsb2FkZWQgZmlyc3QhICovCiAgICAgICAgICAgIC8qIGFzc3VtZSB0aGlzIGlzIGEgY29kaW5nIGVycm9yIG5vdCBhIHJlYWwgZXJyb3IgZm9yIG5vdyAqLwogICAgICAgICAgICBGSVhNRSgiTWlwbWFwIHN1cmZhY2UgaGFzIGEgZ2xUZXh0dXJlIGJvdW5kIHRvIGl0IVxuIik7CiAgICAgICAgfQogICAgfQogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkgewogICAgICAgLyogVGVsbCBvcGVuZ2wgdG8gdHJ5IGFuZCBrZWVwIHRoaXMgdGV4dHVyZSBpbiB2aWRlbyByYW0gKHdlbGwgbW9zdGx5KSAqLwogICAgICAgR0xjbGFtcGYgdG1wOwogICAgICAgdG1wID0gMC45ZjsKICAgICAgICBnbFByaW9yaXRpemVUZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSwgJnRtcCk7CiAgICB9CiAgICAvKiBUT0RPOiBkaXNhYmxlIHRleHR1cmUgc3VwcG9ydCwgaWYgaXQgd2FzdG4ndCBlbmFibGVkIHdoZW4gd2UgZW50ZXJlZC4gKi8KI2lmIDAgLyogVE9ETzogY29udGV4dCBtYW5hZ2VyIHN1cHBvcnQgKi8KICAgICBJV2luZUQzRENvbnRleHRNYW5hZ2VyX1BvcFN0YXRlKFRoaXMtPmNvbnRleHRNYW5hZ2VyLCBHTF9URVhUVVJFXzJELCBESVNBQkxFRCxERUxBWUVECiAgICAgICAgICAgICAgLyogd2UgZG9uJ3QgY2FyZSB3aGVuIHRoZSBzdGF0ZSBpcyBkaXNhYmxlZChpZiBhdGFsbCkgKi8pOwojZW5kaWYKICAgIExFQVZFX0dMKCk7CiAgICB9CiAgICByZXR1cm47Cn0KCldJTkVEM0RSRVNPVVJDRVRZUEUgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0VHlwZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBUUkFDRSgiKCVwKSA6IGNhbGxpbmcgcmVzb3VyY2VpbXBsX0dldFR5cGVcbiIsIGlmYWNlKTsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRUeXBlKChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhcmVudChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJVW5rbm93biAqKnBQYXJlbnQpIHsKICAgIFRSQUNFKCIoJXApIDogY2FsbGluZyByZXNvdXJjZWltcGxfR2V0UGFyZW50XG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UGFyZW50KChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHBQYXJlbnQpOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEU3VyZmFjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lclBhcmVudChJV2luZUQzRFN1cmZhY2UqIGlmYWNlLCBJVW5rbm93biAqKnBwQ29udGFpbmVyUGFyZW50KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IHBwQ29udGFpbmVyUGFyZW50ICVwKVxuIiwgVGhpcywgcHBDb250YWluZXJQYXJlbnQpOwoKICAgIGlmICghcHBDb250YWluZXJQYXJlbnQpIHsKICAgICAgICBFUlIoIiglcCkgOiBDYWxsZWQgd2l0aG91dCBhIHZhbGlkIHBwQ29udGFpbmVyUGFyZW50LlxuIiwgVGhpcyk7CiAgICB9CgogICAgaWYgKFRoaXMtPmNvbnRhaW5lcikgewogICAgICAgIElXaW5lRDNEQmFzZV9HZXRQYXJlbnQoVGhpcy0+Y29udGFpbmVyLCBwcENvbnRhaW5lclBhcmVudCk7CiAgICAgICAgaWYgKCFwcENvbnRhaW5lclBhcmVudCkgewogICAgICAgICAgICAvKiBXaW5lRDNEIG9iamVjdHMgc2hvdWxkIGFsd2F5cyBoYXZlIGEgcGFyZW50ICovCiAgICAgICAgICAgIEVSUigiKCVwKSA6IEdldFBhcmVudCByZXR1cm5lZCBOVUxMXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgSVVua25vd25fUmVsZWFzZSgqcHBDb250YWluZXJQYXJlbnQpOyAvKiBHZXRQYXJlbnQgYWRkcyBhIHJlZmVyZW5jZTsgd2Ugd2FudCBqdXN0IHRoZSBwb2ludGVyICovCiAgICB9IGVsc2UgewogICAgICAgICpwcENvbnRhaW5lclBhcmVudCA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyKElXaW5lRDNEU3VyZmFjZSogaWZhY2UsIFJFRklJRCByaWlkLCB2b2lkKiogcHBDb250YWluZXIpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlICpjb250YWluZXIgPSAwOwoKICAgIFRSQUNFKCIoVGhpcyAlcCwgcmlpZCAlcywgcHBDb250YWluZXIgJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcENvbnRhaW5lcik7CgogICAgaWYgKCFwcENvbnRhaW5lcikgewogICAgICAgIEVSUigiQ2FsbGVkIHdpdGhvdXQgYSB2YWxpZCBwcENvbnRhaW5lci5cbiIpOwogICAgfQoKICAgIC8qKiBGcm9tIE1TRE46CiAgICAgKiBJZiB0aGUgc3VyZmFjZSBpcyBjcmVhdGVkIHVzaW5nIENyZWF0ZUltYWdlU3VyZmFjZS9DcmVhdGVPZmZzY3JlZW5QbGFpblN1cmZhY2UsIENyZWF0ZVJlbmRlclRhcmdldCwKICAgICAqIG9yIENyZWF0ZURlcHRoU3RlbmNpbFN1cmZhY2UsIHRoZSBzdXJmYWNlIGlzIGNvbnNpZGVyZWQgc3RhbmQgYWxvbmUuIEluIHRoaXMgY2FzZSwKICAgICAqIEdldENvbnRhaW5lciB3aWxsIHJldHVybiB0aGUgRGlyZWN0M0QgZGV2aWNlIHVzZWQgdG8gY3JlYXRlIHRoZSBzdXJmYWNlLgogICAgICovCiAgICBpZiAoVGhpcy0+Y29udGFpbmVyKSB7CiAgICAgICAgY29udGFpbmVyID0gVGhpcy0+Y29udGFpbmVyOwogICAgfSBlbHNlIHsKICAgICAgICBjb250YWluZXIgPSAoSVdpbmVEM0RCYXNlICopVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIH0KCiAgICBUUkFDRSgiUmVsYXlpbmcgdG8gUXVlcnlJbnRlcmZhY2VcbiIpOwogICAgaWYgKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGNvbnRhaW5lciwgcmlpZCwgcHBDb250YWluZXIpICE9IFNfT0spCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGVzYyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNEU1VSRkFDRV9ERVNDICpwRGVzYykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBjb3B5aW5nIGludG8gJXBcbiIsIFRoaXMsIHBEZXNjKTsKICAgIGlmKHBEZXNjLT5Gb3JtYXQgIT0gTlVMTCkgICAgICAgICAgICAgKihwRGVzYy0+Rm9ybWF0KSA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgIGlmKHBEZXNjLT5UeXBlICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+VHlwZSkgICA9IFRoaXMtPnJlc291cmNlLnJlc291cmNlVHlwZTsKICAgIGlmKHBEZXNjLT5Vc2FnZSAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+VXNhZ2UpICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnVzYWdlOwogICAgaWYocERlc2MtPlBvb2wgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5Qb29sKSAgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2UucG9vbDsKICAgIGlmKHBEZXNjLT5TaXplICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+U2l6ZSkgICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnNpemU7ICAgLyogZHg4IG9ubHkgKi8KICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVR5cGUgIT0gTlVMTCkgICAgKihwRGVzYy0+TXVsdGlTYW1wbGVUeXBlKSAgICA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlVHlwZTsKICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVF1YWxpdHkgIT0gTlVMTCkgKihwRGVzYy0+TXVsdGlTYW1wbGVRdWFsaXR5KSA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlUXVhbGl0eTsKICAgIGlmKHBEZXNjLT5XaWR0aCAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+V2lkdGgpICAgICAgICAgICAgICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgaWYocERlc2MtPkhlaWdodCAhPSBOVUxMKSAgICAgICAgICAgICAqKHBEZXNjLT5IZWlnaHQpICAgICAgICAgICAgID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0R2xUZXh0dXJlRGVzYyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBVSU5UIHRleHR1cmVOYW1lLCBpbnQgdGFyZ2V0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogc2V0dGluZyB0ZXh0dXJlTmFtZSAldSwgdGFyZ2V0ICVpXG4iLCBUaGlzLCB0ZXh0dXJlTmFtZSwgdGFyZ2V0KTsKICAgIGlmIChUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lID09IDAgJiYgdGV4dHVyZU5hbWUgIT0gMCkgewogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RJUlRZOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGREaXJ0eVJlY3QoaWZhY2UsIE5VTEwpOwogICAgfQogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9IHRleHR1cmVOYW1lOwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQgICAgICA9IHRhcmdldDsKfQoKdm9pZCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRHbERlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgZ2xEZXNjcmlwdG9yICoqZ2xEZXNjcmlwdGlvbikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAlcFxuIiwgVGhpcywgJlRoaXMtPmdsRGVzY3JpcHRpb24pOwogICAgKmdsRGVzY3JpcHRpb24gPSAmVGhpcy0+Z2xEZXNjcmlwdGlvbjsKfQoKLyogVE9ETzogdGhpbmsgYWJvdXQgbW92aW5nIHRoaXMgZG93biB0byByZXNvdXJjZT8gKi8KY29uc3Qgdm9pZCAqV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIC8qIFRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGZvciBzeXNtZW0gdGV4dHVyZXMsIGl0IG1heSBiZSBhIGdvb2QgaWRlYSB0byBleHRlbmQgdGhpcyB0byBhbGwgcG9vbHMgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dHVyZSAgKi8KICAgIGlmIChUaGlzLT5yZXNvdXJjZS5wb29sICE9IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIEZJWE1FKCIgKCVwKUF0dGVtcHRpbmcgdG8gZ2V0IHN5c3RlbSBtZW1vcnkgZm9yIGEgbm9uLXN5c3RlbSBtZW1vcnkgdGV4dHVyZVxuIiwgaWZhY2UpOwogICAgfQogICAgcmV0dXJuIChDT05TVCB2b2lkKikoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNETE9DS0VEX1JFQ1QqIHBMb2NrZWRSZWN0LCBDT05TVCBSRUNUKiBwUmVjdCwgRFdPUkQgRmxhZ3MpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4gPSBOVUxMOwogICAgc3RhdGljIFVJTlQgbWVzc2FnZXMgPSAwOyAvKiBob2xkcyBmbGFncyB0byBkaXNhYmxlIGZpeG1lIG1lc3NhZ2VzICovCgogICAgLyogZml4bWU6IHNob3VsZCB3ZSByZWFsbHkgbG9jayBhcyBzdWNoPyAqLwogICAgaWYoKFRoaXMtPkZsYWdzICYgKFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOUEJVRkZFUikpID09CiAgICAgICAgICAgICAgICAgICAgICAoU0ZMQUdfSU5URVhUVVJFIHwgU0ZMQUdfSU5QQlVGRkVSKSApIHsKICAgICAgICBGSVhNRSgiV2FybmluZzogU3VyZmFjZSBpcyBpbiB0ZXh0dXJlIG1lbW9yeSBvciBwYnVmZmVyXG4iKTsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+KFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOUEJVRkZFUik7CiAgICB9CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLQUJMRSkpIHsKICAgICAgICAvKiBOb3RlOiBVcGRhdGVUZXh0dXJlcyBjYWxscyBDb3B5UmVjdHMgd2hpY2ggY2FsbHMgdGhpcyByb3V0aW5lIHRvIHBvcHVsYXRlIHRoZQogICAgICAgICAgICAgIHRleHR1cmUgcmVnaW9ucywgYW5kIHNpbmNlIHRoZSBkZXN0aW5hdGlvbiBpcyBhbiB1bmxvY2thYmxlIHJlZ2lvbiB3ZSBuZWVkCiAgICAgICAgICAgICAgdG8gdG9sZXJhdGUgdGhpcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICBUUkFDRSgiV2FybmluZzogdHJ5aW5nIHRvIGxvY2sgdW5sb2NrYWJsZSBzdXJmQCVwXG4iLCBUaGlzKTsKICAgICAgICAvKnJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOyAqLwogICAgfQoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKCiAgICAgICAgaWYgKHN3YXBjaGFpbiAhPSBOVUxMIHx8ICBpZmFjZSA9PSBteURldmljZS0+cmVuZGVyVGFyZ2V0IHx8IGlmYWNlID09IG15RGV2aWNlLT5kZXB0aFN0ZW5jaWxCdWZmZXIpIHsKICAgICAgICAgICAgaWYgKHN3YXBjaGFpbiAhPSBOVUxMICYmIGlmYWNlID09ICBzd2FwY2hhaW4tPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCIoJXAsIGJhY2tCdWZmZXIpIDogcmVjdEAlcCBmbGFncyglMDhseCksIG91dHB1dCBsb2NrZWRSZWN0QCVwLCBtZW1vcnlAJXBcbiIsIFRoaXMsIHBSZWN0LCBGbGFncywgcExvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3dhcGNoYWluICE9IE5VTEwgJiYgaWZhY2UgPT0gIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCIoJXAsIGZyb250QnVmZmVyKSA6IHJlY3RAJXAgZmxhZ3MoJTA4bHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLCBUaGlzLCBwUmVjdCwgRmxhZ3MsIHBMb2NrZWRSZWN0LCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCIoJXAsIHJlbmRlclRhcmdldCkgOiByZWN0QCVwIGZsYWdzKCUwOGx4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpZmFjZSA9PSBteURldmljZS0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiKCVwLCBzdGVuY2lsQnVmZmVyKSA6IHJlY3RAJXAgZmxhZ3MoJTA4bHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLCBUaGlzLCBwUmVjdCwgRmxhZ3MsIHBMb2NrZWRSZWN0LCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoTlVMTCAhPSBzd2FwY2hhaW4pIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzd2FwY2hhaW4gPSBOVUxMOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiByZWN0QCVwIGZsYWdzKCUwOGx4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KCiAgICBwTG9ja2VkUmVjdC0+UGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgIGlmIChOVUxMID09IHBSZWN0KSB7CiAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCAgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICBUUkFDRSgiTG9ja2VkIFJlY3QgKCVwKSA9IGwgJWxkLCB0ICVsZCwgciAlbGQsIGIgJWxkXG4iLCAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCwgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiTG9jayBSZWN0ICglcCkgPSBsICVsZCwgdCAlbGQsIHIgJWxkLCBiICVsZFxuIiwgcFJlY3QsIHBSZWN0LT5sZWZ0LCBwUmVjdC0+dG9wLCBwUmVjdC0+cmlnaHQsIHBSZWN0LT5ib3R0b20pOwoKICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgeyAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsgKChwUmVjdC0+bGVmdCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwgLyAyKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsgKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gcFJlY3QtPmxlZnQ7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSBwUmVjdC0+dG9wOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gcFJlY3QtPnJpZ2h0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tID0gcFJlY3QtPmJvdHRvbTsKICAgIH0KCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSB7CiAgICAgICAgVFJBQ0UoIkxvY2tpbmcgbm9uLXBvd2VyIDIgdGV4dHVyZVxuIik7CiAgICB9CgogICAgaWYgKDAgPT0gVGhpcy0+cmVzb3VyY2UudXNhZ2UgfHwgVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgewogICAgICAgIC8qIGNsYXNzaWMgc3VyZmFjZSAgVE9ETzogbm9uIDJkIHN1cmZhY2VzPwogICAgICAgIFRoZXNlIHJlc291cmNlcyBtYXkgYmUgUE9PTF9TWVNURU1NRU0sIHNvIHRoZXkgbXVzdCBub3QgYWNjZXNzIHRoZSBkZXZpY2UgKi8KICAgICAgICBUUkFDRSgibG9ja2luZyBhbiBvcmRpbmFyYXJ5IHN1cmZhY2VcbiIpOwogICAgICAgIC8qIENoZWNrIHRvIHNlZSBpZiBtZW1vcnkgaGFzIGFscmVhZHkgYmVlbiBhbGxvY2F0ZWQgZnJvbSB0aGUgc3VyZmFjZSovCiAgICAgICAgaWYgKChOVUxMID09IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgfHwKICAgICAgICAgICAgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTkVXREMpICl7IC8qIFRPRE86IGNoZWNrIHRvIHNlZSBpZiBhbiB1cGRhdGUgaGFzIGJlZW4gcGVyZm9ybWVkIG9uIHRoZSBzdXJmYWNlIChhbiB1cGRhdGUgY291bGQganVzdCBjbG9iYmVyIGFsbG9jYXRlZE1lbW9yeSAqLwogICAgICAgICAgICAvKiBOb24tc3lzdGVtIG1lbW9yeSBzdXJmYWNlcyAqLwoKICAgICAgICAgICAgLypTdXJmYWNlIGhhcyBubyBtZW1vcnkgY3VycmVudGx5IGFsbG9jYXRlZCB0byBpdCEqLwogICAgICAgICAgICBUUkFDRSgiKCVwKSBMb2NraW5nIHJlY3RcbiIgLCBUaGlzKTsKICAgICAgICAgICAgaWYoIVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCkgLDAgLCBUaGlzLT5wb3cyU2l6ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKDAgIT0gVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgewogICAgICAgICAgICAgICAgLyogTm93IEkgaGF2ZSB0byBjb3B5IHRoaW5nIGJpdHMgYmFjayAqLwogICAgICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQUNUSVZFTE9DSzsgLyogV2hlbiB0aGlzIGZsYWcgaXMgc2V0IHRvIHRydWUsIGxvYWRpbmcgdGhlIHN1cmZhY2UgYWdhaW4gd29uJ3QgZnJlZSBUSGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKi8KICAgICAgICAgICAgICAgIC8qIFRPRE86IG1ha2UgYWN0aXZlTG9jayBhIGJpdCBtb3JlIGludGVsbGlnZW50LCBtYXliZSBpbXBsZW1lbnQgYSBtZXRob2QgdG8gcHVyZ2UgdGhlIHRleHR1cmUgbWVtb3J5LiAqLwogICAgICAgICAgICAgICAgRU5URVJfR0woKTsKICAgIAogICAgICAgICAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgdGhlIHRleHR1cmUgaXMgbG9hZGVkICovCiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7IC8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBhIHRleHR1cmUgdG8gYmluZCEgKi8KICAgIAogICAgICAgICAgICAgICAgVFJBQ0UoIiglcCkgZ2xHZXRUZXhJbWFnZSBsZXZlbCglZCksIGZtdCglZCksIHR5cCglZCksIG1lbSglcClcbiIgLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAKICAgICAgICAgICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fAogICAgICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJMb2NraW5nIGEgY29tcHJlc3NlZCB0ZXh0dXJlXG4iKTsKICAgICAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgeyAvKiB3ZSBjYW4gYXNzdW1lIHRoaXMgYXMgdGhlIHRleHR1cmUgd291bGQgbm90IGhhdmUgYmVlbiBjcmVhdGVkIG90aGVyd2lzZSAqLwogICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIAogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIGF0dGVtcHRpbmcgdG8gbG9jayBhIGNvbXByZXNzZWQgdGV4dHVyZSB3aGVuIHRleHR1cmUgY29tcHJlc3Npb24gaXNuJ3Qgc3VwcG9ydGVkIGJ5IG9wZW5nbFxuIiwgVGhpcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBnbEdldFRleEltYWdlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xHZXRUZXhJbWFnZSIpOwogICAgICAgICAgICAgICAgICAgIGlmIChOUDJfUkVQQUNLID09IHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogc29tZSBnYW1lcyAoZS5nLiB3YXJoYW1tZXIgNDBrKSBkb24ndCB3b3JrIHdpdGggdGhlIG9kZCBwaXRjaHMgcHJvcGVybHksIHByZXZlbnRpbmcKICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHN1cmZhY2UgcGl0Y2ggZnJvbSBiZWluZyB1c2VkIHRvIGJveCBub24tcG93ZXIyIHRleHR1cmVzLiBJbnN0ZWFkIHdlIGhhdmUgdG8gdXNlIGEgaGFjayB0bwogICAgICAgICAgICAgICAgICAgICAgICByZXBhY2sgdGhlIHRleHR1cmUgc28gdGhhdCB0aGUgYnBwICogd2lkdGggcGl0Y2ggY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgYnBwICogcG93MndpZHRoLgogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBXZXJlIGRvaW5nIHRoaXMuLi4KICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGVhZCBvZiBib3hpbmcgdGhlIHRleHR1cmUgOgogICAgICAgICAgICAgICAgICAgICAgICB8PC10ZXh0dXJlIHdpZHRoIC0+fCAgLS0+cG93MndpZHRofCAgIC9cCiAgICAgICAgICAgICAgICAgICAgICAgIHwxMTExMTExMTExMTExMTExMTF8ICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgICAgICAgICAgICB8MjIyIFRleHR1cmUgMjIyMjIyfCBib3hlZCBlbXB0eSAgfCB0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgICAgICAgICAgICB8MzMzMyBEYXRhIDMzMzMzMzMzfCAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgfDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NHwgICAgICAgICAgICAgIHwgICBcLwogICAgICAgICAgICAgICAgICAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgYm94ZWQgIGVtcHR5IHwgYm94ZWQgZW1wdHkgIHwgcG93MmhlaWdodAogICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIHdlcmUgcmVwYWNraW5nIHRoZSBkYXRhIHRvIHRoZSBleHBlY3RlZCB0ZXh0dXJlIHdpZHRoCiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIHw8LXRleHR1cmUgd2lkdGggLT58ICAtLT5wb3cyd2lkdGh8ICAgL1wKICAgICAgICAgICAgICAgICAgICAgICAgfDExMTExMTExMTExMTExMTExMTIyMjIyMjIyMjIyMjIyMnwgICB8CiAgICAgICAgICAgICAgICAgICAgICAgIHwyMjIzMzMzMzMzMzMzMzMzMzMzMzM0NDQ0NDQ0NDQ0NDR8IHRleHR1cmUgaGVpZ2h0CiAgICAgICAgICAgICAgICAgICAgICAgIHw0NDQ0NDQgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgZW1wdHkgICAgICAgICAgICAgICAgfCBwb3cyaGVpZ2h0CiAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgXC8KICAgICAgICAgICAgICAgICAgICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgPT0gaXMgdGhlIHNhbWUgYXMKICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgfDwtdGV4dHVyZSB3aWR0aCAtPnwgICAgL1wKICAgICAgICAgICAgICAgICAgICAgICAgfDExMTExMTExMTExMTExMTExMXwKICAgICAgICAgICAgICAgICAgICAgICAgfDIyMjIyMjIyMjIyMjIyMjIyMnx0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgICAgICAgICAgICB8MzMzMzMzMzMzMzMzMzMzMzMzfAogICAgICAgICAgICAgICAgICAgICAgICB8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0fCAgICBcLwogICAgICAgICAgICAgICAgICAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGFsc28gbWVhbnMgdGhhdCBhbnkgcmVmZXJlbmNlcyB0byBhbGxvY2F0ZWRNZW1vcnkgc2hvdWxkIHdvcmsgd2l0aCB0aGUgZGF0YSBhcyBpZiB3ZXJlIGEgc3RhbmRhcmQgdGV4dHVyZSB3aXRoIGEgbm9uLXBvd2VyMiB3aWR0aCBpbnN0ZWFkIG9mIHRleHR1cmUgYm94ZWQgdXAgdG8gYmUgYSBwb3dlcjIgdGV4dHVyZS4KICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWxseSB0aGUgdGV4dHVyZSBpcyBzdGlsbCBzdG9yZWQgaW4gYSBib3hlZCBmb3JtYXQgc28gYW55IHJlZmVyZW5jZXMgdG8gdGV4dHVyZU5hbWUgd2lsbCBnZXQgYSBib3hlZCB0ZXh0dXJlIHdpdGggd2lkdGggcG93MndpZHRoIGFuZCBub3QgYSB0ZXh0dXJlIG9mIHdpZHRoIGN1cnJlbnREZXNjLldpZHRoLgogICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBCWVRFKiBkYXRhYSwgKmRhdGFiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBpdGNoYSA9IDAsIHBpdGNoYiA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgeTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoYSA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoYiA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhYiA9IGRhdGFhID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgOiBSZXBhY2tpbmcgdGhlIHN1cmZhY2UgZGF0YSBmcm9tIHBpdGNoICVkIHRvIHBpdGNoICVkXG4iLCBUaGlzLCBwaXRjaGEsIHBpdGNoYik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSAxIDsgeSA8IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YWEgKz0gcGl0Y2hhOyAvKiBza2lwIHRoZSBmaXJzdCByb3cgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhYiArPSBwaXRjaGI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRhdGFhLCBkYXRhYiwgcGl0Y2hhKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgeyAvKiBOb3RoaW5nIHRvIGRvICovCiAgICAgICAgICAgIFRSQUNFKCJNZW1vcnkgJXAgYWxyZWFkeSBhbGxvY3RlZCBmb3IgdGV4dHVyZVxuIiwgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoTlVMTCA9PSBwUmVjdCkgewogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgfSAgZWxzZXsKICAgICAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBEM0RGTVRfRFhUMSkgeyAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wKSArICgocFJlY3QtPmxlZnQgKiBUaGlzLT5ieXRlc1BlclBpeGVsIC8gMikpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsgKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSBlbHNlIGlmIChXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUICYgVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiYgIShGbGFncyZXSU5FRDNETE9DS19ESVNDQVJEKSkgeyAvKiByZW5kZXIgc3VyZmFjZXMgKi8KCiAgICAgICAgR0xpbnQgIHByZXZfc3RvcmU7CiAgICAgICAgR0xpbnQgIHByZXZfcmVhZDsKICAgICAgICBCT09MIG5vdEluQ29udGV4dCA9IEZBTFNFOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqdGFyZ2V0U3dhcENoYWluID0gTlVMTDsKCgogICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogZm9yIHJlbmRlci0+c3VyZmFjZSBjb3B5IGJlZ2luIHRvIGJlZ2luIG9mIGFsbG9jYXRlZE1lbW9yeQogICAgICAgICAgICAgKiB1bmxvY2sgY2FuIGJlIG1vcmUgZWFzeQogICAgICAgICAgICAgKi8KCiAgICAgICAgVFJBQ0UoImxvY2tpbmcgYSByZW5kZXIgdGFyZ2V0XG4iKTsKCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9PSBOVUxMKQogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCkgLDAgLFRoaXMtPnJlc291cmNlLnNpemUpOwoKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19BQ1RJVkVMT0NLOyAvKldoZW4gdGhpcyBmbGFnIGlzIHNldCB0byB0cnVlLCBsb2FkaW5nIHRoZSBzdXJmYWNlIGFnYWluIHdvbid0IGZyZWUgVEhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5Ki8KICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CgogICAgICAgIGdsRmx1c2goKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRmx1c2giKTsKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1JFQURfQlVGRkVSLCAmcHJldl9yZWFkKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsSW50ZWdlcnYiKTsKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1BBQ0tfU1dBUF9CWVRFUywgJnByZXZfc3RvcmUpOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xJbnRlZ2VydiIpOwoKIC8qIEhlcmUncyB3aGF0IHdlIGhhdmUgdG8gZG86CiAgICAgICAgICAgIFNlZSBpZiB0aGUgc3dhcGNoYWluIGhhcyB0aGUgc2FtZSBjb250ZXh0IGFzIHRoZSByZW5kZXJUYXJnZXQgb3IgdGhlIHN1cmZhY2UgaXMgdGhlIHJlbmRlciB0YXJnZXQuCiAgICAgICAgICAgIE90aGVyd2lzZSwgc2VlIGlmIHdlcmUgc2hhcmluZyBhIGNvbnRleHQgd2l0aCB0aGUgaW1wbGljaXQgc3dhcGNoYWluIChiZWNhdXNlIHdlJ3JlIHVzaW5nIGEgc2hhcmVkIGNvbnRleHQgbW9kZWwhKQogICAgICAgICAgICBhbmQgdXNlIHRoZSBmcm9udCBiYWNrIGJ1ZmZlciBhcyByZXF1aXJlZC4KICAgICAgICAgICAgaWYgbm90LCB3ZSBuZWVkIHRvIHN3aXRjaCBjb250ZXh0cyBhbmQgdGhlbiBzd2l0Y2hiYWNrIGF0IHRoZSBlbmQuCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihteURldmljZS0+cmVuZGVyVGFyZ2V0LCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmdGFyZ2V0U3dhcENoYWluKTsKCiAgICAgICAgLyogTk9URTogSW4gYSBzaGFyZWQgY29udGV4dCBlbnZpcm9ubWVudCB0aGUgcmVuZGVyVGFyZ2V0IHdpbGwgdXNlIHRoZSBzYW1lIGNvbnRleHQgYXMgdGhlIGltcGxpY2l0IHN3YXBjaGFpbiAod2UncmUgbm90IGluIGEgc2hhcmVkIGVudmlyb25tZW50IHlldCEgKi8KICAgICAgICBpZiAoKHN3YXBjaGFpbiA9PSB0YXJnZXRTd2FwQ2hhaW4gJiYgdGFyZ2V0U3dhcENoYWluICE9IE5VTEwpIHx8IGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgIGlmIChpZmFjZSA9PSBteURldmljZS0+cmVuZGVyVGFyZ2V0IHx8IGlmYWNlID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJsb2NraW5nIGJhY2sgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWZhY2UgPT0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgICAgVFJBQ0UoImxvY2tpbmcgZnJvbnRcbiIpOwogICAgICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPmRlcHRoU3RlbmNpbEJ1ZmZlcikgewogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJTdGVuY2lsIEJ1ZmZlciBsb2NrIHVuc3VwcG9ydGVkIGZvciBub3dcbiIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIFNob3VsZG4ndCBoYXZlIGdvdCBoZXJlIVxuIiwgVGhpcyk7CiAgICAgICAgICAgICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChzd2FwY2hhaW4gIT0gTlVMTCkgewogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKmltcGxTd2FwQ2hhaW47CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX0dldFN3YXBDaGFpbigoSVdpbmVEM0REZXZpY2UgKilteURldmljZSwgMCwgKElXaW5lRDNEU3dhcENoYWluICoqKSZpbXBsU3dhcENoYWluKTsKICAgICAgICAgICAgaWYgKHN3YXBjaGFpbi0+Z2xDdHggPT0gaW1wbFN3YXBDaGFpbi0+cmVuZGVyX2N0eCAmJiBzd2FwY2hhaW4tPmRyYXdhYmxlID09IGltcGxTd2FwQ2hhaW4tPndpbikgewogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgd2lsbCBmYWlsIGZvciB0aGUgaW1wbGljaXQgc3dhcGNoYWluLCB3aGljaCBpcyB3aHkgdGhlcmUgbmVlZHMgdG8gYmUgYSBjb250ZXh0IG1hbmFnZXIgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoaWZhY2UgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IG15RGV2aWNlLT5kZXB0aFN0ZW5jaWxCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlN0ZW5jaWwgQnVmZmVyIGxvY2sgdW5zdXBwb3J0ZWQgZm9yIG5vd1xuIik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlNob3VsZCBoYXZlIGdvdCBoZXJlIVxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBXZSBuZWVkIHRvIHN3aXRjaCBjb250ZXh0cyB0byBiZSBhYmxlIHRvIHJlYWQgdGhlIGJ1ZmZlciEhISAqLwogICAgICAgICAgICAgICAgRklYTUUoIlRoZSBidWZmZXIgcmVxdWVzdGVkIGlzbid0IGluIHRoZSBjdXJyZW50IG9wZW5HTCBjb250ZXh0XG4iKTsKICAgICAgICAgICAgICAgIG5vdEluQ29udGV4dCA9IFRSVUU7CiAgICAgICAgICAgICAgICAvKiBUT0RPOiBjaGVjayB0aGUgY29udGV4dHMsIHRvIHNlZSBpZiB3ZXJlIHNoYXJlZCB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQgKi8KICAgICAgICAgICAgfQogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKWltcGxTd2FwQ2hhaW4pOwogICAgICAgIH0KICAgICAgICBpZiAoc3dhcGNoYWluICE9IE5VTEwpICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgICAgICBpZiAodGFyZ2V0U3dhcENoYWluICE9IE5VTEwpIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopdGFyZ2V0U3dhcENoYWluKTsKCgogICAgICAgIC8qKiB0aGUgZGVwdGggc3RlbmNpbCBpbiBvcGVuR0wgaGFzIGEgZm9ybWF0IG9mIEdMX0ZMT0FUCiAgICAgICAgKiB3aGljaCBzaG91bGQgYmUgZ29vZCBmb3IgV0lORUQzREZNVF9EMTZfTE9DS0FCTEUKICAgICAgICAqIGFuZCBXSU5FRDNERk1UX0QxNgogICAgICAgICogaXQgaXMgdW5jbGVhciB3aGF0IGZvcm1hdCB0aGUgc3RlbmNpbCBidWZmZXIgaXMgaW4gZXhjZXB0LgogICAgICAgICogJ0VhY2ggaW5kZXggaXMgY29udmVydGVkIHRvIGZpeGVkIHBvaW50Li4uCiAgICAgICAgKiBJZiBHTF9NQVBfU1RFTkNJTCBpcyBHTF9UUlVFLCBpbmRpY2VzIGFyZSByZXBsYWNlZCBieSB0aGVpcgogICAgICAgICogbWFwcGluZ3MgaW4gdGhlIHRhYmxlIEdMX1BJWEVMX01BUF9TX1RPX1MuCiAgICAgICAgKiBnbFJlYWRQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICogICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBqIC0gMSwKICAgICAgICAqICAgICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsCiAgICAgICAgKiAgICAgICAgICAgICAxLAogICAgICAgICogICAgICAgICAgICAgR0xfREVQVEhfQ09NUE9ORU5ULAogICAgICAgICogICAgICAgICAgICAgdHlwZSwKICAgICAgICAqICAgICAgICAgICAgIChjaGFyICopcExvY2tlZFJlY3QtPnBCaXRzICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIChqLVRoaXMtPmxvY2tlZFJlY3QudG9wKSkpOwogICAgICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBpZiAoIW5vdEluQ29udGV4dCkgeyAvKiBPbmx5IHJlYWQgdGhlIGJ1ZmZlciBpZiBpdCdzIGluIHRoZSBjdXJyZW50IGNvbnRleHQgKi8KICAgICAgICAgICAgbG9uZyBqOwojaWYgMAogICAgICAgICAgICAvKiBCaXphcmx5IGl0IHRha2VzIDEyMCBtaWxsc2Vjb25kcyB0byBnZXQgYW4gODAweDYwMCByZWdpb24gYSBsaW5lIGF0IGEgdGltZSwgYnV0IG9ubHkgMTAgdG8gZ2V0IHRoZSB3aG9sZSBsb3QgZXZlcnkgdGltZSwKICAgICAgICAgICAgKiAgVGhpcyBpcyBvbiBhbiBBVEk5NjAwLCBhbmQgbWF5IGJlIGZvcm1hdCBkZXBlbmRlbnQsIGFueWhvdyB0aGlzIGhhY2sgbWFrZXMgdGhpcyBkZW1vIGR4OV8yZF9kZW1vX2dhbWUKICAgICAgICAgICAgKiAgcnVuIHRlbiB0aW1lcyBmYXN0ZXIhCiAgICAgICAgICAgICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgICAgICAgICBCT09MIGF0aV9wZXJmb3JtYW5jZV9oYWNrID0gRkFMU0U7CiAgICAgICAgICAgIGF0aV9wZXJmb3JtYW5jZV9oYWNrID0gKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3AgPiAxMCkgfHwgKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgPiAxMCk/IFRSVUU6IEZBTFNFOwojZW5kaWYKICAgICAgICAgICAgaWYgKChUaGlzLT5sb2NrZWRSZWN0LmxlZnQgPT0gMCAmJiAgVGhpcy0+bG9ja2VkUmVjdC50b3AgPT0gMCAmJgogICAgICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCA9PSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aAogICAgICAgICAgICAgICAgJiYgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPT0gIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkpIHsKICAgICAgICAgICAgICAgICAgICBnbFJlYWRQaXhlbHMoMCwgMCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwKICAgICAgICAgICAgICAgICAgICAoY2hhciAqKXBMb2NrZWRSZWN0LT5wQml0cyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0ID09IDAgJiYgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgPT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpIHsKICAgICAgICAgICAgICAgICAgICBnbFJlYWRQaXhlbHMoMCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwKICAgICAgICAgICAgICAgICAgICAoY2hhciAqKXBMb2NrZWRSZWN0LT5wQml0cyk7CiAgICAgICAgICAgIH0gZWxzZXsKCiAgICAgICAgICAgICAgICBmb3IgKGogPSBUaGlzLT5sb2NrZWRSZWN0LnRvcDsgaiA8IFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3A7ICsraikgewogICAgICAgICAgICAgICAgICAgIGdsUmVhZFBpeGVscyhUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIGogLSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhciAqKXBMb2NrZWRSZWN0LT5wQml0cyArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiAoai1UaGlzLT5sb2NrZWRSZWN0LnRvcCkpKTsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRQaXhlbHMiKTsKICAgICAgICAgICAgVFJBQ0UoIlJlc2V0dGluZyBidWZmZXJcbiIpOwogICAgICAgICAgICBnbFJlYWRCdWZmZXIocHJldl9yZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKICAgICAgICB9CiAgICAgICAgTEVBVkVfR0woKTsKCiAgICB9IGVsc2UgaWYgKFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUwgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgeyAvKiBzdGVuY2lsIHN1cmZhY2VzICovCgogICAgICAgIGlmICghbWVzc2FnZXMgJiAxKSB7CiAgICAgICAgICAgIEZJWE1FKCJUT0RPIHN0ZW5jaWwgZGVwdGggc3VyZmFjZSBsb2NraW5nIHN1cmYlcCB1c2FnZSglbHUpXG4iLCBUaGlzLCBUaGlzLT5yZXNvdXJjZS51c2FnZSk7CiAgICAgICAgICAgIC8qCgogICAgICAgICAgICBnbFJlYWRQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIGogLSAxLAogICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICAgICAxLAogICAgICAgICAgICBHTF9TVEVOQ0lMX0lOREVYIG9yIEdMX0RFUFRIX0NPTVBPTkVOVAoKICAgICAgICAgICAgKQogICAgICAgICAgICAqLwogICAgICAgICAgICBtZXNzYWdlcyB8PSAxOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoInVuc3VwcG9ydGVkIGxvY2tpbmcgdG8gc3VyZmFjZSBzdXJmQCVwIHVzYWdlKCVsdSlcbiIsIFRoaXMsIFRoaXMtPnJlc291cmNlLnVzYWdlKTsKICAgIH0KCiAgICBpZiAoRmxhZ3MgJiAoV0lORUQzRExPQ0tfTk9fRElSVFlfVVBEQVRFIHwgV0lORUQzRExPQ0tfUkVBRE9OTFkpKSB7CiAgICAgICAgLyogRG9uJ3QgZGlydGlmeSAqLwogICAgfSBlbHNlIHsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlICpwQmFzZVRleHR1cmU7CiAgICAgICAgLyoqCiAgICAgICAgICogRGlydGlmeSBvbiBsb2NrCiAgICAgICAgICogYXMgc2VlbiBpbiBtc2RuIGRvY3MKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkRGlydHlSZWN0KGlmYWNlLCAmVGhpcy0+bG9ja2VkUmVjdCk7CgogICAgICAgIC8qKiBEaXJ0aWZ5IENvbnRhaW5lciBpZiBuZWVkZWQgKi8KICAgICAgICBpZiAoV0lORUQzRF9PSyA9PSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZwQmFzZVRleHR1cmUpICYmIHBCYXNlVGV4dHVyZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIFRSQUNFKCJNYWtpbmcgY29udGFpbmVyIGRpcnR5XG4iKTsKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXREaXJ0eShwQmFzZVRleHR1cmUsIFRSVUUpOwogICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UocEJhc2VUZXh0dXJlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiU3VyZmFjZSBpcyBzdGFuZGFsb25lLCBubyBuZWVkIHRvIGRpcnR5IHRoZSBjb250YWluZXJcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgicmV0dXJuaW5nIG1lbW9yeUAlcCwgcGl0Y2goJWQpIGRpcnR5ZmllZCglZClcbiIsIHBMb2NrZWRSZWN0LT5wQml0cywgcExvY2tlZFJlY3QtPlBpdGNoLCBUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZID8gMCA6IDEpOwoKICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0xPQ0tFRDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1VubG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgR0xpbnQgc2tpcEJ5dGVzID0gMDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgY29uc3QgY2hhciAqYnVmZmVybmFtZSA9ICIiOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4gPSBOVUxMOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkgewogICAgICAgIFdBUk4oInRyeWluZyB0byBVbmxvY2sgYW4gdW5sb2NrZWQgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwoKICAgICAgICBpZiAoKHN3YXBjaGFpbiAhPSBOVUxMKSAmJiAgaWZhY2UgPT0gIHN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgICAgICAgICAgYnVmZmVybmFtZSA9ICJiYWNrQnVmZmVyIjsKICAgICAgICB9IGVsc2UgaWYgKChzd2FwY2hhaW4gIT0gTlVMTCkgJiYgaWZhY2UgPT0gIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcm5hbWUgPSAiZnJvbnRCdWZmZXIiOwogICAgICAgIH0gZWxzZSBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPmRlcHRoU3RlbmNpbEJ1ZmZlcikgewogICAgICAgICAgICAgICAgYnVmZmVybmFtZSA9ICJkZXB0aFN0ZW5jaWxCdWZmZXIiOwogICAgICAgIH0gZWxzZSBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlclRhcmdldCkgewogICAgICAgICAgICAgICAgYnVmZmVybmFtZSA9ICJyZW5kZXJUYXJnZXQiOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoc3dhcGNoYWluICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbik7CiAgICB9CgogICAgVFJBQ0UoIiglcCAlcykgOiBkaXJ0eWZpZWQoJWQpXG4iLCBUaGlzLCBidWZmZXJuYW1lLCBUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZID8gMSA6IDApOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElSVFkpKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBOb3QgRGlydGlmaWVkIHNvIG5vdGhpbmcgdG8gZG8sIHJldHVybiBub3dcbiIsIFRoaXMpOwogICAgICAgIGdvdG8gdW5sb2NrX2VuZDsKICAgIH0KCiAgICBpZiAoMCA9PSBUaGlzLT5yZXNvdXJjZS51c2FnZSkgeyAvKiBjbGFzc2ljIHN1cmZhY2UgKi8KICAgICAgICAvKioKICAgICAgICAgKiBub3RoaW5nIHRvIGRvCiAgICAgICAgICogd2FpdGluZyB0byByZWxvYWQgdGhlIHN1cmZhY2UgdmlhIElEaXJlY3QzRERldmljZTg6OlVwZGF0ZVRleHR1cmUKICAgICAgICAgKi8KICAgIH0gZWxzZSBpZiAoV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCAmIFRoaXMtPnJlc291cmNlLnVzYWdlKSB7IC8qIHJlbmRlciBzdXJmYWNlcyAqLwoKICAgICAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICAgICogVE9ETzogUmVuZGVyIHRhcmdldHMgYXJlICdzcGVjaWFsJyBhbmQKICAgICAgICAqID9zb21lPyBsb2NraW5nIG5lZWRzIHRvIGJlIHBhc3NlZCBvbnRvIHRoZSBjb250ZXh0IG1hbmFnZXIKICAgICAgICAqIHNvIHRoYXQgaXQgYmVjb21lcyBwb3NzaWJsZSB0byB1c2UgYXV4aWxpYXJ5IGJ1ZmZlcnMsIHBidWZmZXJzCiAgICAgICAgKiByZW5kZXItdG8tdGV4dHVyZSwgc2hhcmVkLCBjYWNoZWQgY29udGV4dHMgZXRjLi4uCiAgICAgICAgKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqaW1wbFN3YXBDaGFpbjsKICAgICAgICBJV2luZUQzRERldmljZV9HZXRTd2FwQ2hhaW4oKElXaW5lRDNERGV2aWNlICopbXlEZXZpY2UsIDAsIChJV2luZUQzRFN3YXBDaGFpbiAqKikmaW1wbFN3YXBDaGFpbik7CgogICAgICAgIGlmIChpZmFjZSA9PSAgaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlciB8fCBpZmFjZSA9PSAgaW1wbFN3YXBDaGFpbi0+ZnJvbnRCdWZmZXIgfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlclRhcmdldCkgewogICAgICAgICAgICBHTGludCAgcHJldl9zdG9yZTsKICAgICAgICAgICAgR0xpbnQgIHByZXZfZHJhdzsKICAgICAgICAgICAgR0xpbnQgIHByZXZfcmFzdGVycG9zWzRdOwoKICAgICAgICAgICAgLyogU29tZSBkcml2ZXJzKHJhZGVvbiBkcmksIG90aGVycz8pIGRvbid0IGxpa2UgZXhjZXB0aW9ucyBkdXJpbmcKICAgICAgICAgICAgICogZ2xEcmF3UGl4ZWxzLiBJZiB0aGUgc3VyZmFjZSBpcyBhIERJQiBzZWN0aW9uLCBpdCBtaWdodCBiZSBpbiBHRElNb2RlCiAgICAgICAgICAgICAqIGFmdGVyIFJlbGVhc2VEQy4gUmVhZGluZyBpdCB3aWxsIGNhdXNlIGFuIGV4Y2VwdGlvbiwgd2hpY2ggeDExZHJ2IHdpbGwKICAgICAgICAgICAgICogY2F0Y2ggdG8gcHV0IHRoZSBkaWIgc2VjdGlvbiBpbiBJblN5bmMgbW9kZSwgd2hpY2ggbGVhZHMgdG8gYSBjcmFzaAogICAgICAgICAgICAgKiBhbmQgYSBibG9ja2VkIHggc2VydmVyIG9uIG15IHJhZGVvbiBjYXJkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBUaGUgZm9sbG93aW5nIGxpbmVzIHJlYWQgdGhlIGRpYiBzZWN0aW9uIHNvIGl0IGlzIHB1dCBpbiBpblN5bmMgbW9kZQogICAgICAgICAgICAgKiBiZWZvcmUgZ2xEcmF3UGl4ZWxzIGlzIGNhbGxlZCBhbmQgdGhlIGNyYXNoIGlzIHByZXZlbnRlZC4gVGhlcmUgd29uJ3QKICAgICAgICAgICAgICogYmUgYW55IGludGVyZmVyaW5nIGdkaSBhY2Nlc3NlcywgYmVjYXVzZSBVbmxvY2tSZWN0IGlzIGNhbGxlZCBmcm9tCiAgICAgICAgICAgICAqIFJlbGVhc2VEQywgYW5kIHRoZSBhcHAgd29uJ3QgdXNlIHRoZSBkYyBhbnkgbW9yZSBhZnRlcndhcmRzLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICB2b2xhdGlsZSBCWVRFIHJlYWQ7CiAgICAgICAgICAgICAgICByZWFkID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5WzBdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgZ2xGbHVzaCgpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRmx1c2giKTsKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9EUkFXX0JVRkZFUiwgJnByZXZfZHJhdyk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xJbnRlZ2VydiIpOwogICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX1BBQ0tfU1dBUF9CWVRFUywgJnByZXZfc3RvcmUpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsSW50ZWdlcnYiKTsKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9DVVJSRU5UX1JBU1RFUl9QT1NJVElPTiwgJnByZXZfcmFzdGVycG9zWzBdKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CiAgICAgICAgICAgIGdsUGl4ZWxab29tKDEuMCwgLTEuMCk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFpvb20iKTsKCiAgICAgICAgICAgIC8qIGdsRHJhd1BpeGVscyB0cmFuc2Zvcm1zIHRoZSByYXN0ZXIgcG9zaXRpb24gYXMgdGhvdWdoIGl0IHdhcyBhIHZlcnRleCAtCiAgICAgICAgICAgICAgIHdlIHdhbnQgdG8gZHJhdyBhdCBzY3JlZW4gcG9zaXRpb24gMCwwIC0gU2V0IHVwIG9ydGhvIChyaHcpIG1vZGUgYXMKICAgICAgICAgICAgICAgcGVyIGRyYXdwcmltIChhbmQgbGVhdmUgc2V0IC0gaXQgd2lsbCBzb3J0IGl0c2VsZiBvdXQgZHVlIHRvIGxhc3Rfd2FzX3JodyAqLwogICAgICAgICAgICBpZiAoICghbXlEZXZpY2UtPmxhc3Rfd2FzX3JodykgfHwgKG15RGV2aWNlLT52aWV3cG9ydF9jaGFuZ2VkKSApIHsKCiAgICAgICAgICAgICAgICBkb3VibGUgWCwgWSwgaGVpZ2h0LCB3aWR0aCwgbWluWiwgbWF4WjsKICAgICAgICAgICAgICAgIG15RGV2aWNlLT5sYXN0X3dhc19yaHcgPSBUUlVFOwogICAgICAgICAgICAgICAgbXlEZXZpY2UtPnZpZXdwb3J0X2NoYW5nZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICAvKiBUcmFuc2Zvcm1lZCBhbHJlYWR5IGludG8gdmlld3BvcnQgY29vcmRpbmF0ZXMsIHNvIHdlIGRvIG5vdCBuZWVkIHRyYW5zZm9ybQogICAgICAgICAgICAgICAgICAgbWF0cmljZXMuIFJlc2V0IGFsbCBtYXRyaWNlcyB0byBpZGVudGl0eSBhbmQgbGVhdmUgdGhlIGRlZmF1bHQgbWF0cml4IGluIHdvcmxkCiAgICAgICAgICAgICAgICAgICBtb2RlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xNYXRyaXhNb2RlIik7CiAgICAgICAgICAgICAgICBnbExvYWRJZGVudGl0eSgpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsTG9hZElkZW50aXR5Iik7CgogICAgICAgICAgICAgICAgZ2xNYXRyaXhNb2RlKEdMX1BST0pFQ1RJT04pOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsTWF0cml4TW9kZSIpOwogICAgICAgICAgICAgICAgZ2xMb2FkSWRlbnRpdHkoKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbExvYWRJZGVudGl0eSIpOwoKICAgICAgICAgICAgICAgIC8qIFNldCB1cCB0aGUgdmlld3BvcnQgdG8gYmUgZnVsbCB2aWV3cG9ydCAqLwogICAgICAgICAgICAgICAgWCAgICAgID0gbXlEZXZpY2UtPnN0YXRlQmxvY2stPnZpZXdwb3J0Llg7CiAgICAgICAgICAgICAgICBZICAgICAgPSBteURldmljZS0+c3RhdGVCbG9jay0+dmlld3BvcnQuWTsKICAgICAgICAgICAgICAgIGhlaWdodCA9IG15RGV2aWNlLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5IZWlnaHQ7CiAgICAgICAgICAgICAgICB3aWR0aCAgPSBteURldmljZS0+c3RhdGVCbG9jay0+dmlld3BvcnQuV2lkdGg7CiAgICAgICAgICAgICAgICBtaW5aICAgPSBteURldmljZS0+c3RhdGVCbG9jay0+dmlld3BvcnQuTWluWjsKICAgICAgICAgICAgICAgIG1heFogICA9IG15RGV2aWNlLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5NYXhaOwogICAgICAgICAgICAgICAgVFJBQ0UoIkNhbGxpbmcgZ2xPcnRobyB3aXRoICVmLCAlZiwgJWYsICVmXG4iLCB3aWR0aCwgaGVpZ2h0LCAtbWluWiwgLW1heFopOwogICAgICAgICAgICAgICAgZ2xPcnRobyhYLCBYICsgd2lkdGgsIFkgKyBoZWlnaHQsIFksIC1taW5aLCAtbWF4Wik7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xPcnRobyIpOwoKICAgICAgICAgICAgICAgIC8qIFdpbmRvdyBDb29yZCAwIGlzIHRoZSBtaWRkbGUgb2YgdGhlIGZpcnN0IHBpeGVsLCBzbyB0cmFuc2xhdGUgYnkgaGFsZgogICAgICAgICAgICAgICAgICAgYSBwaXhlbCAoU2VlIGNvbW1lbnQgYWJvdmUgZ2xUcmFuc2xhdGUgYmVsb3cpICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBnbFRyYW5zbGF0ZWYoMC41LCAwLjUsIDApOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVHJhbnNsYXRlZigwLjUsIDAuNSwgMCkiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlmYWNlID09ICBpbXBsU3dhcENoYWluLT5iYWNrQnVmZmVyIHx8IGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpZmFjZSA9PSAgaW1wbFN3YXBDaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CgogICAgICAgICAgICAvKiBJZiBub3QgZnVsbHNjcmVlbiwgd2UgbmVlZCB0byBza2lwIGEgbnVtYmVyIG9mIGJ5dGVzIHRvIGZpbmQgdGhlIG5leHQgcm93IG9mIGRhdGEgKi8KICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgJnNraXBCeXRlcyk7CiAgICAgICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKTsKCiAgICAgICAgICAgIC8qIEFuZCBiYWNrIGJ1ZmZlcnMgYXJlIG5vdCBibGVuZGVkICovCiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CgogICAgICAgICAgICBnbFJhc3RlclBvczNpKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgVGhpcy0+bG9ja2VkUmVjdC50b3AsIDEpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmFzdGVyUG9zMmYiKTsKICAgICAgICAgICAgc3dpdGNoIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpIHsKCSAgICBjYXNlIFdJTkVEM0RGTVRfWDRSNEc0QjQ6CgkgICAgICAgIHsKCQkgICAgaW50IHNpemU7CiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgKmRhdGE7CiAgICAgICAgICAgICAgICAgICAgZGF0YSA9ICh1bnNpZ25lZCBzaG9ydCAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgICAgICAgICBzaXplID0gKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApICogKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKHNpemUgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqZGF0YSB8PSAweEYwMDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgICAgICAgICAgfQoJCX0KCSAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CgkgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnbERyYXdQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsIEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzRfUkVWLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xEcmF3UGl4ZWxzIik7CgkgICAgICAgIH0KCQlicmVhazsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnbERyYXdQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbERyYXdQaXhlbHMiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDFSNUc1QjU6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW50IHNpemU7CiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgKmRhdGE7CiAgICAgICAgICAgICAgICAgICAgZGF0YSA9ICh1bnNpZ25lZCBzaG9ydCAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgICAgICAgICBzaXplID0gKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApICogKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKHNpemUgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqZGF0YSB8PSAweDgwMDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKS0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLCBHTF9VTlNJR05FRF9TSE9SVF8xXzVfNV81X1JFViwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRHJhd1BpeGVscyIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKS0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0IsIEdMX1VOU0lHTkVEX0JZVEUsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbERyYXdQaXhlbHMiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhSOEc4Qjg6IC8qIG1ha2Ugc3VyZSB0aGUgWCBieXRlIGlzIHNldCB0byBhbHBoYSBvbiwgc2luY2UgaXQgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VsZCBiZSBhbnkgcmFuZG9tIHZhbHVlIHRoaXMgZml4ZXMgdGhlIGludHJvIG1vdmUgaW4gUGlyYXRlcyEgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZTsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgKmRhdGE7CiAgICAgICAgICAgICAgICAgICAgZGF0YSA9ICh1bnNpZ25lZCBpbnQgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKSAqIChUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0KTsKICAgICAgICAgICAgICAgICAgICB3aGlsZShzaXplID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgKmRhdGEgfD0gMHhGRjAwMDAwMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGErKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUtLTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BOFI4RzhCODoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfU1dBUF9CWVRFUywgVFJVRSk7CiAgICAgICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpIik7CiAgICAgICAgICAgICAgICAgICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKS0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9CR1JBLCBHTF9VTlNJR05FRF9CWVRFLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xEcmF3UGl4ZWxzIik7CiAgICAgICAgICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX1NXQVBfQllURVMsIHByZXZfc3RvcmUpOwogICAgICAgICAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfU1dBUF9CWVRFUywgVFJVRSk7CiAgICAgICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpIik7CiAgICAgICAgICAgICAgICAgICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKS0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9CR1JBLCBHTF9VTlNJR05FRF9JTlRfMl8xMF8xMF8xMF9SRVYsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbERyYXdQaXhlbHMiKTsKICAgICAgICAgICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfU1dBUF9CWVRFUywgcHJldl9zdG9yZSk7CiAgICAgICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBGb3JtYXQgJXUgaW4gbG9ja2luZyBmdW5jXG4iLCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBnbFBpeGVsWm9vbSgxLjAsMS4wKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsWm9vbSIpOwogICAgICAgICAgICBnbERyYXdCdWZmZXIocHJldl9kcmF3KTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIiKTsKICAgICAgICAgICAgZ2xSYXN0ZXJQb3MzaXYoJnByZXZfcmFzdGVycG9zWzBdKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJhc3RlclBvczNpdiIpOwoKICAgICAgICAgICAgLyogUmVzZXQgdG8gcHJldmlvdXMgcGFjayByb3cgbGVuZ3RoIC8gYmxlbmRpbmcgc3RhdGUgKi8KICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgc2tpcEJ5dGVzKTsKICAgICAgICAgICAgaWYgKG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19BTFBIQUJMRU5ERU5BQkxFXSkgZ2xFbmFibGUoR0xfQkxFTkQpOwoKICAgICAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgICAgIC8qKiByZXN0b3JlIGNsZWFuIGRpcnR5IHN0YXRlICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9DbGVhbkRpcnR5UmVjdChpZmFjZSk7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCB1bmxvY2tpbmcgdG8gUmVuZGVyaW5nIHN1cmZhY2Ugc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICAgICAgfQogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopaW1wbFN3YXBDaGFpbik7CgogICAgfSBlbHNlIGlmIChXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMICYgVGhpcy0+cmVzb3VyY2UudXNhZ2UpIHsgLyogc3RlbmNpbCBzdXJmYWNlcyAqLwoKICAgICAgICBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPmRlcHRoU3RlbmNpbEJ1ZmZlcikgewogICAgICAgICAgICBGSVhNRSgiVE9ETyBzdGVuY2lsIGRlcHRoIHN1cmZhY2UgdW5sb2NraW5nIHN1cmZAJXAgdXNhZ2UoJWx1KVxuIiwgVGhpcywgVGhpcy0+cmVzb3VyY2UudXNhZ2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCB1bmxvY2tpbmcgdG8gU3RlbmNpbERlcHRoIHN1cmZhY2Ugc3VyZkAlcCB1c2FnZSglbHUpXG4iLCBUaGlzLCBUaGlzLT5yZXNvdXJjZS51c2FnZSk7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoInVuc3VwcG9ydGVkIHVubG9ja2luZyB0byBzdXJmYWNlIHN1cmZAJXAgdXNhZ2UoJXMpXG4iLCBUaGlzLCBkZWJ1Z19kM2R1c2FnZShUaGlzLT5yZXNvdXJjZS51c2FnZSkpOwogICAgfQoKICAgIHVubG9ja19lbmQ6CiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9DS0VEOwogICAgbWVtc2V0KCZUaGlzLT5sb2NrZWRSZWN0LCAwLCBzaXplb2YoUkVDVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0REMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDICpwSERDKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCBsb2NrOwogICAgVUlOVCB1c2FnZTsKICAgIEJJVE1BUElORk8qIGJfaW5mbzsKICAgIEhEQyBkZGM7CiAgICBEV09SRCAqbWFza3M7CiAgICBIUkVTVUxUIGhyOwogICAgUkdCUVVBRCBjb2xbMjU2XTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLHBIREMpOwoKICAgIC8qIEdpdmUgbW9yZSBkZXRhaWxlZCBpbmZvIGZvciBkZHJhdyAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkKICAgICAgICByZXR1cm4gRERFUlJfRENBTFJFQURZQ1JFQVRFRDsKCiAgICAvKiBDYW4ndCBHZXREQyBpZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1zZXQoJmxvY2ssIDAsIHNpemVvZihsb2NrKSk7IC8qIFRvIGJlIHN1cmUgKi8KCiAgICAvKiBDcmVhdGUgYSBESUIgc2VjdGlvbiBpZiB0aGVyZSBpc24ndCBhIGhkYyB5ZXQgKi8KICAgIGlmKCFUaGlzLT5oREMpIHsKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0FDVElWRUxPQ0spIHsKICAgICAgICAgICAgRVJSKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdoaWxlIGEgbG9jayBpcyBhY3RpdmUuIFVuY2VydGFpbiBjb25zZXF1ZW5jZXNcbiIpOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChUaGlzLT5ieXRlc1BlclBpeGVsKSB7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgLyogQWxsb2NhdGUgZXh0cmEgc3BhY2UgdG8gc3RvcmUgdGhlIFJHQiBiaXQgbWFza3MuICovCiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgMyAqIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8qIEFsbG9jYXRlIGV4dHJhIHNwYWNlIGZvciBhIHBhbGV0dGUuICovCiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoUkdCUVVBRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKDEgPDwgKFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiA4KSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVNpemUgPSBzaXplb2YoQklUTUFQSU5GT0hFQURFUik7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlXaWR0aCA9IFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUhlaWdodCA9IC1UaGlzLT5wb3cySGVpZ2h0OwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpUGxhbmVzID0gMTsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUJpdENvdW50ID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDg7CgogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlID0gVGhpcy0+cmVzb3VyY2Uuc2l6ZTsKCiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlYUGVsc1Blck1ldGVyID0gMDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVlQZWxzUGVyTWV0ZXIgPSAwOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9IDA7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDbHJJbXBvcnRhbnQgPSAwOwoKICAgICAgICAvKiBHZXQgdGhlIGJpdCBtYXNrcyAqLwogICAgICAgIG1hc2tzID0gKERXT1JEICopICYoYl9pbmZvLT5ibWlDb2xvcnMpOwogICAgICAgIHN3aXRjaCAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgICAgICB1c2FnZSA9IERJQl9SR0JfQ09MT1JTOwogICAgICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDb21wcmVzc2lvbiA9IEJJX1JHQjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1gxUjVHNUI1OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSM0czQjI6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4QjhHOFI4OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhCOEc4Ujg6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExNkIxNkcxNlIxNjoKICAgICAgICAgICAgICAgIHVzYWdlID0gMDsKICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9CSVRGSUVMRFM7CiAgICAgICAgICAgICAgICBtYXNrc1swXSA9IGdldF9iaXRtYXNrX3JlZChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgICAgICAgICAgbWFza3NbMV0gPSBnZXRfYml0bWFza19ncmVlbihUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgICAgICAgICAgbWFza3NbMl0gPSBnZXRfYml0bWFza19ibHVlKFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvKiBEb24ndCBrbm93IHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgICAgICB1c2FnZSA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRkYyA9IENyZWF0ZURDQSgiRElTUExBWSIsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIGlmIChkZGMgPT0gMCkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdpdGggc2l6ZSAlbGR4JWxkeCVkLCBzaXplPSVsZFxuIiwgYl9pbmZvLT5ibWlIZWFkZXIuYmlXaWR0aCwgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICBUaGlzLT5kaWIuRElCc2VjdGlvbiA9IENyZWF0ZURJQlNlY3Rpb24oZGRjLCBiX2luZm8sIHVzYWdlLCAmVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCAwIC8qIEhhbmRsZSAqLywgMCAvKiBPZmZzZXQgKi8pOwogICAgICAgIERlbGV0ZURDKGRkYyk7CgogICAgICAgIGlmICghVGhpcy0+ZGliLkRJQnNlY3Rpb24pIHsKICAgICAgICAgICAgRVJSKCJDcmVhdGVESUJTZWN0aW9uIGZhaWxlZCFcbiIpOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKCiAgICAgICAgVFJBQ0UoIkRJQlNlY3Rpb24gYXQgOiAlcFxuIiwgVGhpcy0+ZGliLmJpdG1hcF9kYXRhKTsKCiAgICAgICAgLyogY29weSB0aGUgZXhpc3Rpbmcgc3VyZmFjZSB0byB0aGUgZGliIHNlY3Rpb24gKi8KICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICAgICAgbWVtY3B5KFRoaXMtPmRpYi5iaXRtYXBfZGF0YSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBUaGlzLT5yZXNvdXJjZS5zaXplKTsKICAgICAgICAgICAgLyogV2Ugd29uJ3QgbmVlZCB0aGF0IGFueSBtb3JlICovCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgfQoKICAgICAgICAvKiBVc2UgdGhlIGRpYiBzZWN0aW9uIGZyb20gbm93IG9uICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwoKICAgICAgICAvKiBOb3cgYWxsb2NhdGUgYSBIREMgKi8KICAgICAgICBUaGlzLT5oREMgPSBDcmVhdGVDb21wYXRpYmxlREMoMCk7CiAgICAgICAgVGhpcy0+ZGliLmhvbGRiaXRtYXAgPSBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgVFJBQ0UoInVzaW5nIHdpbmVkM2QgcGFsZXR0ZSAlcFxuIiwgVGhpcy0+cGFsZXR0ZSk7CiAgICAgICAgU2VsZWN0UGFsZXR0ZShUaGlzLT5oREMsCiAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYWxldHRlID8gVGhpcy0+cGFsZXR0ZS0+aHBhbCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICBGQUxTRSk7CgogICAgICAgIC8qIFRoaXMgaXMgdG8gbWFrZSBMb2NrUmVjdCByZWFkIHRoZSBnbCBUZXh0dXJlIGFsdGhvdWdoIG1lbW9yeSBpcyBhbGxvY2F0ZWQgKi8KICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ORVdEQzsKCiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRElCU0VDVElPTjsKICAgIH0KCiAgICAvKiBMb2NrIHRoZSBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX05FV0RDOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIEVSUigiSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0IGZhaWxlZCB3aXRoIGhyID0gJTA4bHhcbiIsIGhyKTsKICAgICAgICAvKiBrZWVwIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fAogICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgbjsKICAgICAgICBpZihUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgIFBBTEVUVEVFTlRSWSBlbnRbMjU2XTsKCiAgICAgICAgICAgIEdldFBhbGV0dGVFbnRyaWVzKFRoaXMtPnBhbGV0dGUtPmhwYWwsIDAsIDI1NiwgZW50KTsKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGVudFtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGVudFtuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gZW50W25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVCbHVlOwogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlc2VydmVkID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgU2V0RElCQ29sb3JUYWJsZShUaGlzLT5oREMsIDAsIDI1NiwgY29sKTsKICAgIH0KCiAgICAqcEhEQyA9IFRoaXMtPmhEQzsKICAgIFRSQUNFKCJyZXR1cm5pbmcgJXBcbiIsKnBIREMpOwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlREMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDIGhEQykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxoREMpOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkpCiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICAvKiB3ZSBsb2NrZWQgZmlyc3QsIHNvIHVubG9jayBub3cgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJbnRlcm5hbCAoTm8gbWFwcGluZyB0byBkaXJlY3R4IGFwaSkgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRUZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkgewogICAgICAgIFRSQUNFKCJTdXJmYWNlIGFscmVhZHkgaW4gdGV4dHVyZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZKSkgewogICAgICAgIFRSQUNFKCJzdXJmYWNlIGlzbid0IGRpcnR5XG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRElSVFk7CgogICAgLyogUmVzb3VyY2VzIGFyZSBwbGFjZWQgaW4gc3lzdGVtIFJBTSBhbmQgZG8gbm90IG5lZWQgdG8gYmUgcmVjcmVhdGVkIHdoZW4gYSBkZXZpY2UgaXMgbG9zdC4KICAgICogIFRoZXNlIHJlc291cmNlcyBhcmUgbm90IGJvdW5kIGJ5IGRldmljZSBzaXplIG9yIGZvcm1hdCByZXN0cmljdGlvbnMuIEJlY2F1c2Ugb2YgdGhpcywKICAgICogIHRoZXNlIHJlc291cmNlcyBjYW5ub3QgYmUgYWNjZXNzZWQgYnkgdGhlIERpcmVjdDNEIGRldmljZSBub3Igc2V0IGFzIHRleHR1cmVzIG9yIHJlbmRlciB0YXJnZXRzLgogICAgKiAgSG93ZXZlciwgdGhlc2UgcmVzb3VyY2VzIGNhbiBhbHdheXMgYmUgY3JlYXRlZCwgbG9ja2VkLCBhbmQgY29waWVkLgogICAgKiAgSW4gZ2VuZXJhbCBuZXZlciBzdG9yZSBzY3JhdGNoIG9yIHN5c3RlbSBtZW0gdGV4dHVyZXMgaW4gdGhlIHZpZGVvIHJhbS4gSG93ZXZlciBpdCBpcyBhbGxvd2VkCiAgICAqICBmb3Igc3lzdGVtIG1lbW9yeSB0ZXh0dXJlcyB3aGVuIFdJTkVEM0RERVZDQVBTX1RFWFRVUkVTWVNURU1NRU1PUlkgaXMgc2V0IGJ1dCBpdCBpc24ndCByaWdodCBub3cuCiAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCB8fCBUaGlzLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKSBPcGVyYXRpb24gbm90IHN1cHBvcnRlZCBmb3Igc2NyYXRjaCBvciBTWVNURU1NRU0gdGV4dHVyZXNcbiIsVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5QQlVGRkVSKSB7CiAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwgIT0gMCkKICAgICAgICAgICAgRklYTUUoIlN1cmZhY2UgaW4gdGV4dHVyZSBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgbGV2ZWwgMFxuIik7CiAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpCiAgICAgICAgICAgIEZJWE1FKCJGb3JtYXQgJWQgbm90IHN1cHBvcnRlZFxuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgR0xpbnQgcHJldlJlYWQ7CiAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZwcmV2UmVhZCk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xHZXRJbnRlZ2VydiIpOwogICAgICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CgogICAgICAgICAgICBnbENvcHlUZXhJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CgogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4SW1hZ2UyRCIpOwogICAgICAgICAgICBnbFJlYWRCdWZmZXIocHJldlJlYWQpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwogICAgICAgICAgICBUUkFDRSgiVXBkYXRpbmcgdGFyZ2V0ICVkXG4iLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOVEVYVFVSRTsKICAgICAgICB9CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZiAoKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpICYmCiAgICAgICAgIUdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpKSB7CiAgICAgICAgLyoqCiAgICAgICAgICogd2FudGVkIGEgcGFsZXR0ZWQgdGV4dHVyZSBhbmQgbm90IHJlYWxseSBzdXBwb3J0IGl0IGluIEhXCiAgICAgICAgICogc28gc29mdHdhcmUgZW11bGF0aW9uIGNvZGUgYmVnaW4KICAgICAgICAgKi8KICAgICAgICBVSU5UIGk7CiAgICAgICAgUEFMRVRURUVOVFJZKiBwYWwgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5wYWxldHRlc1tUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5jdXJyZW50UGFsZXR0ZV07CiAgICAgICAgVk9JRCogc3VyZmFjZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCAqIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCAqIHNpemVvZihEV09SRCkpOwogICAgICAgIEJZVEUqIGRzdCA9IChCWVRFKikgc3VyZmFjZTsKICAgICAgICBCWVRFKiBzcmMgPSAoQllURSopIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICogVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OyBpKyspIHsKICAgICAgICAgICAgQllURSBjb2xvciA9ICpzcmMrKzsKICAgICAgICAgICAgKmRzdCsrID0gcGFsW2NvbG9yXS5wZVJlZDsKICAgICAgICAgICAgKmRzdCsrID0gcGFsW2NvbG9yXS5wZUdyZWVuOwogICAgICAgICAgICAqZHN0KysgPSBwYWxbY29sb3JdLnBlQmx1ZTsKICAgICAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpCiAgICAgICAgICAgICAgICAqZHN0KysgPSBwYWxbY29sb3JdLnBlRmxhZ3M7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICpkc3QrKyA9IDB4RkY7CiAgICAgICAgfQoKICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICBUUkFDRSgiQ2FsbGluZyBnbFRleEltYWdlMkQgJXggaT0lZCwgaW50Zm10PSV4LCB3PSVkLCBoPSVkLDA9JWQsIGdsRm10PSV4LCBnbFR5cGU9JXgsIE1lbT0lcFxuIiwKICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LAogICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICBHTF9VTlNJR05FRF9CWVRFLAogICAgICAgICAgICAgIHN1cmZhY2UpOwogICAgICAgIGdsVGV4SW1hZ2UyRChUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgR0xfVU5TSUdORURfQllURSwKICAgICAgICAgICAgICAgICAgICAgc3VyZmFjZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4SW1hZ2UyRCIpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN1cmZhY2UpOwoKICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBUT0RPOiBDb21wcmVzc2VkIG5vbi1wb3dlciAyIHN1cHBvcnQgKi8KCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fAogICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwKICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fAogICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBpZiAoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsKICAgICAgICAgICAgRklYTUUoIlVzaW5nIERYVDEvMy81IHdpdGhvdXQgYWR2ZXJ0aXplZCBzdXBwb3J0XG4iKTsKICAgICAgICB9IGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICBUUkFDRSgiQ2FsbGluZyBnbENvbXByZXNzZWRUZXhJbWFnZTJEICV4IGk9JWQsIGludGZtdD0leCwgdz0lZCwgaD0lZCwwPSVkLCBzej0lZCwgTWVtPSVwXG4iLAogICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplLAogICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwoKICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDb21wcmVzc2VkVGV4SW1hZ2UyREFSQikoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb21tcHJlc3NlZFRleEltYWdlMkQiKTsKCiAgICAgICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgICAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfRE9OT1RGUkVFKSl7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CgogICAgICAgLyogVE9ETzogcG9zc2libHkgdXNlIHRleHR1cmUgcmVjdGFuZ2xlICh0aG91Z2ggd2UgYXJlIHByb2JhYmx5IG1vcmUgY29tcGF0aWJsZSB3aXRob3V0IGl0KSAqLwogICAgICAgIGlmIChOUDJfUkVQQUNLID09IHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUgJiYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTk9OUE9XMikpIHsKCgogICAgICAgICAgICBUUkFDRSgibm9uIHBvd2VyIG9mIHR3byBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ2FsbGluZyAyIGdsVGV4SW1hZ2UyRCAleCBpPSVkLCBkM2RmbXQ9JXMsIGludGZtdD0leCwgdz0lZCwgaD0lZCwwPSVkLCBnbEZtdD0leCwgZ2xUeXBlPSV4LCBNZW09JXBcbiIsIFRoaXMsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBkZWJ1Z19kM2Rmb3JtYXQoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCwKICAgICAgICAgICAgICAgIFRoaXMtPnBvdzJXaWR0aCwKICAgICAgICAgICAgICAgIFRoaXMtPnBvdzJIZWlnaHQsCiAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLAogICAgICAgICAgICAgICAgTlVMTCk7CgogICAgICAgICAgICBnbFRleEltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cG93MldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cG93MkhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgIDAvKmJvcmRlciovLAogICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CgogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CiAgICAgICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ2FsbGluZyBnbFRleFN1YkltYWdlMkQgdyglZCkgaCglZCkgbWVtKCVwKVxuIiwgVGhpcywgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgICAgIC8qIEFuZCBtYXAgdGhlIG5vbi1wb3dlciB0d28gZGF0YSBpbnRvIHRoZSB0b3AgbGVmdCBjb3JuZXIgKi8KICAgICAgICAgICAgICAgIGdsVGV4U3ViSW1hZ2UyRCgKICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgIDAgLyogeG9mZnNldCAqLywKICAgICAgICAgICAgICAgICAgICAwIC8qIHlzb2Zmc2V0ICovICwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhTdWJJbWFnZTJEIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgfSBlbHNlIHsKCiAgICAgICAgICAgIFRSQUNFKCJDYWxsaW5nIDIgZ2xUZXhJbWFnZTJEICV4IGk9JWQsIGQzZGZtdD0lcywgaW50Zm10PSV4LCB3PSVkLCBoPSVkLDA9JWQsIGdsRm10PSV4LCBnbFR5cGU9JXgsIE1lbT0lcFxuIiwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpLAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgVGhpcy0+cG93MldpZHRoLAogICAgICAgICAgICAgICAgVGhpcy0+cG93MkhlaWdodCwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUsCiAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwoKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgZ2xUZXhJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnBvdzJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cG93MkhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBib3JkZXIgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQoKI2lmIDAKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICAgICAgY2hhciBidWZmZXJbNDA5Nl07CiAgICAgICAgICAgICsrZ2VuOwogICAgICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLCAiL3RtcC9zdXJmYWNlJXBfdHlwZSV1X2xldmVsJXVfJXUucHBtIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGdlbik7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChpZmFjZSwgYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkZWJ1Z2dpbmcgY3Jhc2ggY29kZQogICAgICAgICAgICBpZiAoZ2VuID09IDI1MCkgewogICAgICAgICAgICAgIHZvaWQqKiB0ZXN0ID0gTlVMTDsKICAgICAgICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKi8KICAgICAgICB9CiNlbmRpZgogICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ET05PVEZSRUUpKXsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBjb25zdCBjaGFyKiBmaWxlbmFtZSkgewogICAgRklMRSogZiA9IE5VTEw7CiAgICBVSU5UIGksIHk7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNoYXIgKmFsbG9jYXRlZE1lbW9yeTsKICAgIGNoYXIgKnRleHR1cmVSb3c7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCB3aWR0aCwgaGVpZ2h0OwogICAgR0x1aW50IHRtcFRleHR1cmU7CiAgICBEV09SRCBjb2xvcjsKICAgIC8qRklYTUU6CiAgICBUZXh0dXJlcyBteSBub3QgYmUgc3RvcmVkIGluIC0+YWxsb2NhdGVkZ01lbW9yeSBhbmQgYSBHbFRleHR1cmUKICAgIHNvIHdlIHNob3VsZCBsb2NrIHRoZSBzdXJmYWNlIGJlZm9yZSBzYXZpbmcgYSBzbmFwc2hvdCwgb3IgYXQgbGVhc3QgY2hlY2sgdGhhdAogICAgKi8KICAgIC8qIFRPRE86IENvbXByZXNzZWQgdGV4dHVyZSBpbWFnZXMgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlIEdMIGluIHVuY29tcHJlc3NlZCBmb3JtCiAgICBieSBjYWxsaW5nIEdldFRleEltYWdlIGFuZCBpbiBjb21wcmVzc2VkIGZvcm0gYnkgY2FsbGluZwogICAgR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCLiAgUXVlcmllZCBjb21wcmVzc2VkIGltYWdlcyBjYW4gYmUgc2F2ZWQgYW5kCiAgICBsYXRlciByZXVzZWQgYnkgY2FsbGluZyBDb21wcmVzc2VkVGV4SW1hZ2VbMTIzXURBUkIuICBQcmUtY29tcHJlc3NlZAogICAgdGV4dHVyZSBpbWFnZXMgZG8gbm90IG5lZWQgdG8gYmUgcHJvY2Vzc2VkIGJ5IHRoZSBHTCBhbmQgc2hvdWxkCiAgICBzaWduaWZpY2FudGx5IGltcHJvdmUgdGV4dHVyZSBsb2FkaW5nIHBlcmZvcm1hbmNlIHJlbGF0aXZlIHRvIHVuY29tcHJlc3NlZAogICAgaW1hZ2VzLiAqLwoKLyogU2V0dXAgdGhlIHdpZHRoIGFuZCBoZWlnaHQgdG8gYmUgdGhlIGludGVybmFsIHRleHR1cmUgd2lkdGggYW5kIGhlaWdodC4gKi8KICAgIHdpZHRoICA9IFRoaXMtPnBvdzJXaWR0aDsKICAgIGhlaWdodCA9IFRoaXMtPnBvdzJIZWlnaHQ7Ci8qIGNoZWNrIHRvIHNlZSBpZiB3ZXJlIGEgJ3ZpcnR1YWwnIHRleHR1cmUgZS5nLiB3ZXJlIG5vdCBhIHBidWZmZXIgb2YgdGV4dHVyZSB3ZXJlIGEgYmFjayBidWZmZXIqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBDaGFpbik7CgogICAgaWYgKHN3YXBDaGFpbiB8fCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlBCVUZGRVIpKSB7IC8qIGlmIHdlcmUgbm90IGEgcmVhbCB0ZXh0dXJlIHRoZW4gcmVhZCB0aGUgYmFjayBidWZmZXIgaW50byBhIHJlYWwgdGV4dHVyZSovCi8qIHdlIGRvbid0IHdhbnQgdG8gaW50ZXJmZXJlIHdpdGggdGhlIGJhY2sgYnVmZmVyIHNvIHJlYWQgdGhlIGRhdGEgaW50byBhIHRlbXBvcmFyeSB0ZXh0dXJlIGFuZCB0aGVuIHNhdmUgdGhlIGRhdGEgb3V0IG9mIHRoZSB0ZW1wb3JhcnkgdGV4dHVyZSAqLwogICAgICAgIEdMaW50IHByZXZSZWFkOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgRklYTUUoIiglcCkgVGhpcyBzdXJmYWNlIG5lZWRzIHRvIGJlIGxvY2tlZCBiZWZvcmUgYSBzbmFwc2hvdCBjYW4gYmUgdGFrZW5cbiIsIFRoaXMpOwogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwoKICAgICAgICBnbEdlblRleHR1cmVzKDEsICZ0bXBUZXh0dXJlKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRtcFRleHR1cmUpOwoKICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgMC8qYm9yZGVyKi8sCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFViwKICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CgogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZwcmV2UmVhZCk7CiAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2Iik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CiAgICAgICAgZ2xDb3B5VGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CgogICAgICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhJbWFnZTJEIik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKHByZXZSZWFkKTsKICAgICAgICBMRUFWRV9HTCgpOwoKICAgIH0gZWxzZSB7IC8qIGJpbmQgdGhlIHJlYWwgdGV4dHVyZSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGlmYWNlKTsKICAgIH0KICAgIGFsbG9jYXRlZE1lbW9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCB3aWR0aCAgKiBoZWlnaHQgKiA0KTsKICAgIEVOVEVSX0dMKCk7CiAgICBGSVhNRSgiU2F2aW5nIHRleHR1cmUgbGV2ZWwgJWQgd2lkdGggJWQgaGVpZ2h0ICVkXG4iLCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCB3aWR0aCwgaGVpZ2h0KTsKICAgIGdsR2V0VGV4SW1hZ2UoR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgR0xfVU5TSUdORURfSU5UXzhfOF84XzhfUkVWLAogICAgICAgICAgICAgICAgYWxsb2NhdGVkTWVtb3J5KTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKICAgIGlmICh0bXBUZXh0dXJlKSB7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZ0bXBUZXh0dXJlKTsKICAgIH0KICAgIExFQVZFX0dMKCk7CgogICAgZiA9IGZvcGVuKGZpbGVuYW1lLCAidysiKTsKICAgIGlmIChOVUxMID09IGYpIHsKICAgICAgICBFUlIoIm9wZW5pbmcgb2YgJXMgZmFpbGVkIHdpdGg6ICVzXG4iLCBmaWxlbmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KLyogU2F2ZSB0aGUgZGF0IG91dCB0byBhIFRHQSBmaWxlIGJlY2F1c2UgMTogaXQncyBhbiBlYXN5IHJhdyBmb3JtYXQsIDI6IGl0IHN1cHBvcnRzIGFuIGFscGhhIGNoYW5lbCovCiAgICBUUkFDRSgiKCVwKSBvcGVuZWQgJXMgd2l0aCBmb3JtYXQgJXNcbiIsIFRoaXMsIGZpbGVuYW1lLCBkZWJ1Z19kM2Rmb3JtYXQoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSk7Ci8qIFRHQSBoZWFkZXIgKi8KICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMixmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKLyogc2hvcnQgd2lkdGgqLwogICAgZndyaXRlKCZ3aWR0aCwyLDEsZik7Ci8qIHNob3J0IGhlaWdodCAqLwogICAgZndyaXRlKCZoZWlnaHQsMiwxLGYpOwovKiBmb3JtYXQgcmdiYSAqLwogICAgZnB1dGMoMHgyMCxmKTsKICAgIGZwdXRjKDB4MjgsZik7Ci8qIHJhdyBkYXRhICovCiAgICAvKiBpZiAgdGhlIGRhdGEgaXMgdXBzaWRlIGRvd24gaWYgd2UndmUgZmV0Y2hlZCBpdCBmcm9tIGEgYmFjayBidWZmZXIsIHNvIGl0IG5lZWRzIGZsaXBwaW5nIGFnYWluIHRvIG1ha2UgaXQgdGhlIGNvcnJlY3Qgd2F5IHVwKi8KICAgIGlmKHN3YXBDaGFpbikKICAgICAgICB0ZXh0dXJlUm93ID0gYWxsb2NhdGVkTWVtb3J5ICsgKHdpZHRoICogKGhlaWdodCAtIDEpICo0KTsKICAgIGVsc2UKICAgICAgICB0ZXh0dXJlUm93ID0gYWxsb2NhdGVkTWVtb3J5OwogICAgZm9yICh5ID0gMCA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCB3aWR0aDsgIGkrKykgewogICAgICAgICAgICBjb2xvciA9ICooKERXT1JEKil0ZXh0dXJlUm93KTsKICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+IDE2KSAmIDB4RkYsIGYpOyAvKiBCICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAgOCkgJiAweEZGLCBmKTsgLyogRyAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gIDApICYgMHhGRiwgZik7IC8qIFIgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+IDI0KSAmIDB4RkYsIGYpOyAvKiBBICovCiAgICAgICAgICAgIHRleHR1cmVSb3cgKz0gNDsKICAgICAgICB9CiAgICAgICAgLyogdGFrZSB0d28gcm93cyBvZiB0aGUgcG9pbnRlciB0byB0aGUgdGV4dHVyZSBtZW1vcnkgKi8KICAgICAgICBpZihzd2FwQ2hhaW4pCiAgICAgICAgICAgICh0ZXh0dXJlUm93LT0gd2lkdGggPDwgMyk7CgogICAgfQogICAgVFJBQ0UoIkNsb3NpbmcgZmlsZVxuIik7CiAgICBmY2xvc2UoZik7CgogICAgaWYoc3dhcENoYWluKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYWxsb2NhdGVkTWVtb3J5KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0NsZWFuRGlydHlSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RJUlRZOwogICAgVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgVGhpcy0+ZGlydHlSZWN0LnRvcCAgICA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIFRoaXMtPmRpcnR5UmVjdC5yaWdodCAgPSAwOwogICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IDA7CiAgICBUUkFDRSgiKCVwKSA6IERpcnR5PyVkLCBSZWN0OiglbGQsJWxkLCVsZCwlbGQpXG4iLCBUaGlzLCBUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZID8gMSA6IDAsIFRoaXMtPmRpcnR5UmVjdC5sZWZ0LAogICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCwgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0LCBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioKICogICBTbGlnaHRseSBpbmVmZmljaWVudCB3YXkgdG8gaGFuZGxlIG11bHRpcGxlIGRpcnR5IHJlY3RzIGJ1dCBpdCB3b3JrcyA6KQogKi8KZXh0ZXJuIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIENPTlNUIFJFQ1QqIHBEaXJ0eVJlY3QpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqYmFzZVRleHR1cmUgPSBOVUxMOwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRElSVFk7CiAgICBpZiAoTlVMTCAhPSBwRGlydHlSZWN0KSB7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9IG1pbihUaGlzLT5kaXJ0eVJlY3QubGVmdCwgICBwRGlydHlSZWN0LT5sZWZ0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC50b3AsICAgIHBEaXJ0eVJlY3QtPnRvcCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0ICA9IG1heChUaGlzLT5kaXJ0eVJlY3QucmlnaHQsICBwRGlydHlSZWN0LT5yaWdodCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IG1heChUaGlzLT5kaXJ0eVJlY3QuYm90dG9tLCBwRGlydHlSZWN0LT5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogRGlydHk/JWQsIFJlY3Q6KCVsZCwlbGQsJWxkLCVsZClcbiIsIFRoaXMsIFRoaXMtPkZsYWdzICYgU0ZMQUdfRElSVFksIFRoaXMtPmRpcnR5UmVjdC5sZWZ0LAogICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCwgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0LCBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tKTsKICAgIC8qIGlmIHRoZSBjb250YWluZXIgaXMgYSBiYXNldGV4dHVyZSB0aGVuIG1hcmsgaXQgZGlydHkuICovCiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb25hdGluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0RGlydHkoYmFzZVRleHR1cmUsIFRSVUUpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShiYXNlVGV4dHVyZSk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb250YWluZXIoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RCYXNlICpjb250YWluZXIpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCJUaGlzICVwLCBjb250YWluZXIgJXBcbiIsIFRoaXMsIGNvbnRhaW5lcik7CgogICAgLyogV2UgY2FuJ3Qga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgY29udGFpbmVyLCBzaW5jZSB0aGUgY29udGFpbmVyIGFscmVhZHkga2VlcHMgYSByZWZlcmVuY2UgdG8gdXMuICovCgogICAgVFJBQ0UoIlNldHRpbmcgY29udGFpbmVyIHRvICVwIGZyb20gJXBcbiIsIGNvbnRhaW5lciwgVGhpcy0+Y29udGFpbmVyKTsKICAgIFRoaXMtPmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzREZPUk1BVCBmb3JtYXQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBUaGUgZm9yYW10IG9mIHRoZSBzdXJmYWNlIG11c3QgYmUgV0lORUQzREZPUk1BVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgdGV4dHVyZSBmb3JhbXQgdG8gKCVkLCVzKVxuIiwgVGhpcywgZm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoZm9ybWF0KSk7CiAgICBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAwOwogICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxKSB7CiAgICAgICAgLyogRFhUMSBpcyBoYWxmIGJ5dGUgcGVyIHBpeGVsICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgobWF4KFRoaXMtPnBvdzJXaWR0aCwgNCkgKiBEM0RGbXRHZXRCcHAoVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSwgZm9ybWF0KSkgKiBtYXgoVGhpcy0+cG93MkhlaWdodCwgNCkpID4+IDE7CgogICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgICAgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgobWF4KFRoaXMtPnBvdzJXaWR0aCwgNCkgKiBEM0RGbXRHZXRCcHAoVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSwgZm9ybWF0KSkgKiBtYXgoVGhpcy0+cG93MkhlaWdodCwgNCkpOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKFRoaXMtPnBvdzJXaWR0aCAqIEQzREZtdEdldEJwcChUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLCBmb3JtYXQpKSAqIFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9CgoKICAgIC8qIFNldHVwIHNvbWUgZ2xmb3JtYXQgZGVmYXVsdHMgKi8KICAgIGlmIChmb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCAgICAgICAgID0gRDNERm10MkdMRm10KFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UsIGZvcm1hdCk7CiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsID0gRDNERm10MkdMSW50Rm10KFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UsIGZvcm1hdCk7CiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gRDNERm10MkdMVHlwZShUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLCBmb3JtYXQpOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0ICAgICAgICAgPSAwOwogICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCA9IDA7CiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gMDsKICAgIH0KCiAgICBpZiAoZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRoaXMtPmJ5dGVzUGVyUGl4ZWwgPSBEM0RGbXRHZXRCcHAoVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSwgZm9ybWF0KTsKICAgICAgICBUaGlzLT5wb3cyU2l6ZSAgICAgID0gKFRoaXMtPnBvdzJXaWR0aCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpICogVGhpcy0+cG93MkhlaWdodDsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+Ynl0ZXNQZXJQaXhlbCA9IDA7CiAgICAgICAgVGhpcy0+cG93MlNpemUgICAgICA9IDA7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgfD0gKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IGZvcm1hdCkgPyBTRkxBR19MT0NLQUJMRSA6IDA7CgogICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID0gZm9ybWF0OwoKICAgIFRSQUNFKCIoJXApIDogU2l6ZSAlZCwgcG93MlNpemUgJWQsIGJ5dGVzUGVyUGl4ZWwgJWQsIGdsRm9ybWF0ICVkLCBnbEZvdG1hdEludGVybmFsICVkLCBnbFR5cGUgJWRcbiIsIFRoaXMsIFRoaXMtPnJlc291cmNlLnNpemUsIFRoaXMtPnBvdzJTaXplLCBUaGlzLT5ieXRlc1BlclBpeGVsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVE9ETzogcmVwbGFjZSB0aGlzIGZ1bmN0aW9uIHdpdGggY29udGV4dCBtYW5hZ2VtZW50IHJvdXRpbmVzICovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UEJ1ZmZlclN0YXRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEJPT0wgaW5QQnVmZmVyLCBCT09MICBpblRleHR1cmUpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmKGluUEJ1ZmZlcikgewogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOUEJVRkZFUjsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOUEJVRkZFUjsKICAgIH0KCiAgICBpZihpblRleHR1cmUpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlRFWFRVUkU7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfRmxpcChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKm92ZXJyaWRlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZSAqRDNEID0gKElXaW5lRDNERGV2aWNlICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVseClcbiIsIFRoaXMsIG92ZXJyaWRlLCBGbGFncyk7CgogICAgLyogRmxpcHBpbmcgaXMgb25seSBzdXBwb3J0ZWQgb24gUmVuZGVyVGFyZ2V0cyAqLwogICAgaWYoICEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSApIHJldHVybiBEREVSUl9OT1RGTElQUEFCTEU7CgogICAgaWYob3ZlcnJpZGUpIHsKICAgICAgICAvKiBERHJhdyBzZXRzIHRoaXMgZm9yIHRoZSBYMTEgc3VyZmFjZXMsIHNvIGRvbid0IGNvbmZ1c2UgdGhlIHVzZXIgCiAgICAgICAgICogRklYTUUoIiglcCkgVGFyZ2V0IG92ZXJyaWRlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgbm93XG4iLCBUaGlzKTsKICAgICAgICAgKiBBZGRpdGlvbmFsbHksIGl0IGlzbid0IHJlYWxseSBwb3NzaWJsZSB0byBzdXBwb3J0IHRyaXBsZS1idWZmZXJpbmcKICAgICAgICAgKiBwcm9wZXJseSBvbiBvcGVuZ2wgYXQgYWxsCiAgICAgICAgICovCiAgICB9CgogICAgLyogRmxpcHBpbmcgYSBPcGVuR0wgc3VyZmFjZSAtPiBVc2UgV2luZUQzRERldmljZTo6UHJlc2VudCAqLwogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlX1ByZXNlbnQoRDNELCBOVUxMLCBOVUxMLCAwLCBOVUxMKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVDVCAqRGVzdFJlY3QsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgUkVDVCAqU3JjUmVjdCwgRFdPUkQgRmxhZ3MsIEREQkxURlggKkREQmx0RngpIHsKICAgIEZJWE1FKCJUaGlzIGlzIHVuaW1wbGVtZW50ZWQgZm9yIG5vdyhkM2Q3IG1lcmdlKVxuIik7CiAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgRmxhZ3MpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglbHgpXG4iLCBUaGlzLCBGbGFncyk7CgogICAgc3dpdGNoIChGbGFncykKICAgIHsKICAgIGNhc2UgRERHQlNfQ0FOQkxUOgogICAgY2FzZSBEREdCU19JU0JMVERPTkU6CiAgICAgICAgcmV0dXJuIEREX09LOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgLyogWFhYOiBEREVSUl9JTlZBTElEU1VSRkFDRVRZUEUgKi8KCiAgICBUUkFDRSgiKCVwKS0+KCUwOGx4KVxuIixpZmFjZSxGbGFncyk7CiAgICBzd2l0Y2ggKEZsYWdzKSB7CiAgICBjYXNlIERER0ZTX0NBTkZMSVA6CiAgICBjYXNlIERER0ZTX0lTRkxJUERPTkU6CiAgICAgICAgcmV0dXJuIEREX09LOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfSXNMb3N0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gVGhpcy0+RmxhZ3MgJiBTRkxBR19MT1NUID8gRERFUlJfU1VSRkFDRUxPU1QgOiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1Jlc3RvcmUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIFNvIGZhciB3ZSBkb24ndCBsb3NlIGFueXRoaW5nIDopICovCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9TVDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdEZhc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgZHN0eCwgRFdPUkQgZHN0eSwgSVdpbmVEM0RTdXJmYWNlICpTb3VyY2UsIFJFQ1QgKnJzcmMsIERXT1JEIHRyYW5zKSB7CiAgICBGSVhNRSgiVGhpcyBpcyB1bmltcGxlbWVudGVkIGZvciBub3coZDNkNyBtZXJnZSlcbiIpOwogICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UGl4ZWxGb3JtYXQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzREZPUk1BVCBGb3JtYXQsIEJZVEUgKlN1cmZhY2UsIERXT1JEIFNpemUpIHsKICAgIEZJWE1FKCJUaGlzIGlzIHVuaW1wbGVtZW50ZWQgZm9yIG5vdyhkM2Q3IG1lcmdlKVxuIik7CiAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEUGFsZXR0ZSAqKlBhbCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIFBhbCk7CgogICAgKlBhbCA9IChJV2luZUQzRFBhbGV0dGUgKikgVGhpcy0+cGFsZXR0ZTsKICAgIHJldHVybiBERF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqcGFsID0gVGhpcy0+cGFsZXR0ZTsKICAgIHVuc2lnbmVkIGludCBuOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4IHx8CiAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4KQogICAgewogICAgICAgIFRSQUNFKCJEaXJ0aWZ5aW5nIHN1cmZhY2VcbiIpOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RJUlRZOwogICAgfQoKICAgIFRSQUNFKCIoJXApOiBVcGRhdGluZyB0aGUgcGFsZXR0ZVxuIiwgVGhpcyk7CiAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IHBhbC0+cGFsZW50c1tuXS5wZVJlZDsKICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBwYWwtPnBhbGVudHNbbl0ucGVHcmVlbjsKICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBwYWwtPnBhbGVudHNbbl0ucGVCbHVlOwogICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICB9CiAgICBTZXRESUJDb2xvclRhYmxlKFRoaXMtPmhEQywgMCwgMjU2LCBjb2wpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICpQYWwpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKlBhbEltcGwgPSAoSVdpbmVEM0RQYWxldHRlSW1wbCAqKSBQYWw7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICBpZihUaGlzLT5wYWxldHRlICE9IE5VTEwpIAogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgICAgICAgICAgVGhpcy0+cGFsZXR0ZS0+RmxhZ3MgJj0gfkREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CgogICAgaWYoUGFsSW1wbCAhPSBOVUxMKSB7CiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgICAgIC8qIFNldCB0aGUgZGV2aWNlJ3MgbWFpbiBwYWxldHRlIGlmIHRoZSBwYWxldHRlCiAgICAgICAgICAgICAqIHdhc24ndCBhIHByaW1hcnkgcGFsZXR0ZSBiZWZvcmUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKCEoUGFsSW1wbC0+RmxhZ3MgJiBERFBDQVBTX1BSSU1BUllTVVJGQUNFKSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGk7CgogICAgICAgICAgICAgICAgZm9yKGk9MDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXSA9IFBhbEltcGwtPnBhbGVudHNbaV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIChQYWxJbXBsKS0+RmxhZ3MgfD0gRERQQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgICAgICB9CiAgICB9CiAgICBUaGlzLT5wYWxldHRlID0gUGFsSW1wbDsKCiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1JlYWxpemVQYWxldHRlKGlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb2xvcktleShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncywgRERDT0xPUktFWSAqQ0tleSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgQk9PTCBkaXJ0aWZ5ID0gRkFMU0U7CiAgICBUUkFDRSgiKCVwKS0+KCUwOGx4LCVwKVxuIiwgVGhpcywgRmxhZ3MsIENLZXkpOwoKICAgIGlmICgoRmxhZ3MgJiBERENLRVlfQ09MT1JTUEFDRSkgIT0gMCkgewogICAgICAgIEZJWE1FKCIgY29sb3JrZXkgdmFsdWUgbm90IHN1cHBvcnRlZCAoJTA4bHgpICFcbiIsIEZsYWdzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBEaXJ0aWZ5IHRoZSBzdXJmYWNlLCBidXQgb25seSBpZiBhIGtleSB3YXMgY2hhbmdlZCAqLwogICAgaWYoQ0tleSkgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpIHsKICAgICAgICAgICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgICAgIGlmKCEoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS0RFU1RCTFQpKSB7CiAgICAgICAgICAgICAgICAgICAgZGlydGlmeSA9IFRSVUU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGRpcnRpZnkgPSBtZW1jbXAoJlRoaXMtPkRlc3RCbHRDS2V5LCBDS2V5LCBzaXplb2YoKkNLZXkpICkgIT0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFRoaXMtPkRlc3RCbHRDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICAgICAgaWYoIShUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLREVTVE9WRVJMQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgZGlydGlmeSA9IFRSVUU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGRpcnRpZnkgPSBtZW1jbXAoJlRoaXMtPkRlc3RPdmVybGF5Q0tleSwgQ0tleSwgc2l6ZW9mKCpDS2V5KSkgIT0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFRoaXMtPkRlc3RPdmVybGF5Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IEREU0RfQ0tERVNUT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfU1JDT1ZFUkxBWToKICAgICAgICAgICAgICAgIGlmKCEoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ09WRVJMQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgZGlydGlmeSA9IFRSVUU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGRpcnRpZnkgPSBtZW1jbXAoJlRoaXMtPlNyY092ZXJsYXlDS2V5LCBDS2V5LCBzaXplb2YoKkNLZXkpKSAhPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVGhpcy0+U3JjT3ZlcmxheUNLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICAgICAgaWYoIShUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkgewogICAgICAgICAgICAgICAgICAgIGRpcnRpZnkgPSBUUlVFOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBkaXJ0aWZ5ID0gbWVtY21wKCZUaGlzLT5TcmNCbHRDS2V5LCBDS2V5LCBzaXplb2YoKkNLZXkpKSAhPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IEREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBzd2l0Y2ggKEZsYWdzICYgfkREQ0tFWV9DT0xPUlNQQUNFKSB7CiAgICAgICAgICAgIGNhc2UgRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgICAgICBkaXJ0aWZ5ID0gVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9ERVNUT1ZFUkxBWToKICAgICAgICAgICAgICAgIGRpcnRpZnkgPSBUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tERVNUT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfU1JDT1ZFUkxBWToKICAgICAgICAgICAgICAgIGRpcnRpZnkgPSBUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+RERTRF9DS1NSQ09WRVJMQVk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRERDS0VZX1NSQ0JMVDoKICAgICAgICAgICAgICAgIGRpcnRpZnkgPSBUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUOwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5ERFNEX0NLU1JDQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmKGRpcnRpZnkpIHsKICAgICAgICBUUkFDRSgiQ29sb3Iga2V5IGNoYW5nZWQsIGRpcnRpZmluZyBzdXJmYWNlXG4iKTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESVJUWTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgLyogTm90aGluZyB0byBkbyBmb3Igbm93ICovCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKRFdPUkQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGl0Y2goSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgRFdPUkQgcmV0OwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIERYVG4gZm9ybWF0cyBkb24ndCBoYXZlIGV4YWN0IHBpdGNoZXMgYXMgdGhleSBhcmUgdG8gdGhlIG5ldyByb3cgb2YgYmxvY2tzLAogICAgICAgICB3aGVyZSBlYWNoIGJsb2NrIGlzIDR4NCBwaXhlbHMsIDggYnl0ZXMgKGR4dDEpIGFuZCAxNiBieXRlcyAoZHh0Mi8zLzQvNSkKICAgICAgICAgIGllIHBpdGNoID0gKHdpZHRoLzQpICogYnl0ZXMgcGVyIGJsb2NrICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgLyogRFhUMSBpcyA4IGJ5dGVzIHBlciBibG9jayAqLwogICAgICAgIHJldCA9IChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCA+PiAyKSA8PCAzOwogICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIC8qIERYVDIvMy80LzUgaXMgMTYgYnl0ZXMgcGVyIGJsb2NrICovCiAgICAgICAgcmV0ID0gKFRoaXMtPmN1cnJlbnREZXNjLldpZHRoID4+IDIpIDw8IDQ7CiAgICBlbHNlIHsKICAgICAgICBpZiAoTlAyX1JFUEFDSyA9PSB3aW5lZDNkX3NldHRpbmdzLm5vbnBvd2VyMl9tb2RlIHx8IFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgICAgICAvKiBGcm9udCBhbmQgYmFjayBidWZmZXJzIGFyZSBhbHdheXMgbG9ja2VzL3VubG9ja2VkIG9uIGN1cnJlbnREZXNjLldpZHRoICovCiAgICAgICAgICAgIHJldCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsgIC8qIEJ5dGVzIC8gcm93ICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0ID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICB9CiAgICB9CiAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgJWxkXG4iLCBUaGlzLCByZXQpOwogICAgcmV0dXJuIHJldDsKfQoKY29uc3QgSVdpbmVEM0RTdXJmYWNlVnRibCBJV2luZUQzRFN1cmZhY2VfVnRibCA9CnsKICAgIC8qIElVbmtub3duICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGRSZWYsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2UsCiAgICAvKiBJV2luZUQzRFJlc291cmNlICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhcmVudCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGV2aWNlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpb3JpdHksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaW9yaXR5LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9QcmVMb2FkLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRUeXBlLAogICAgLyogSVdpbmVEM0RTdXJmYWNlICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lclBhcmVudCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVW5sb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0REMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2VEQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfRmxpcCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0lzTG9zdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVzdG9yZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0RmFzdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UGl4ZWxGb3JtYXQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlYWxpemVQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb2xvcktleSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGl0Y2gsCiAgICAvKiBJbnRlcm5hbCB1c2U6ICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0NsZWFuRGlydHlSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGREaXJ0eVJlY3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRUZXh0dXJlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbnRhaW5lciwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UEJ1ZmZlclN0YXRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRHbFRleHR1cmVEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRHbERlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEZvcm1hdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwCn07Cg==