LyoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIGludGVybmFsIGludGVyZmFjZSB0byBnZXQgYWNjZXNzIHRvIHRhYmxlIG9mIHN0cmVhbSBpbiBhbiBlZGl0YWJsZSBzdHJlYW0gKi8KCnR5cGVkZWYgc3RydWN0IF9FZGl0U3RyZWFtVGFibGUgewogIFBBVklTVFJFQU0gcFN0cmVhbTsgIC8qIHN0cmVhbSB3aGljaCBjb250YWlucyB0aGUgZGF0YSAqLwogIERXT1JEICAgICAgZHdTdGFydDsgIC8qIHdoZXJlIHN0YXJ0cyB0aGUgcGFydCB3aGljaCBpcyBhbHNvIG91ciAqLwogIERXT1JEICAgICAgZHdMZW5ndGg7IC8qIGhvdyBtYW55IGlzIGFsc28gaW4gdGhpcyBzdHJlYW0gKi8KfSBFZGl0U3RyZWFtVGFibGU7CgojZGVmaW5lIElOVEVSRkFDRSBJRWRpdFN0cmVhbUludGVybmFsCkRFQ0xBUkVfSU5URVJGQUNFXyhJRWRpdFN0cmVhbUludGVybmFsLElVbmtub3duKQp7CiAgICAvKioqIElVbmtub3duIG1ldGhvZHMgKioqLwogICAgU1RETUVUSE9EXyhIUkVTVUxULFF1ZXJ5SW50ZXJmYWNlKShUSElTXyBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwdk9iamVjdCkgUFVSRTsKICAgIFNURE1FVEhPRF8oVUxPTkcsQWRkUmVmKShUSElTKSBQVVJFOwogICAgU1RETUVUSE9EXyhVTE9ORyxSZWxlYXNlKShUSElTKSBQVVJFOwogICAgLyoqKiBJRWRpdFN0cmVhbUludGVybmFsIG1ldGhvZHMgKioqLwogICAgU1RETUVUSE9EKEdldEVkaXRTdHJlYW1JbXBsKShUSElTXyBMUFZPSUQqKSBQVVJFOwp9OwojdW5kZWYgSU5URVJGQUNFCgojZGVmaW5lIEVkaXRTdHJlYW1FbmQoVGhpcyxzdHJlYW1OcikgKChUaGlzKS0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgKyBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMpLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGgpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJRWRpdFN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQWRkUmVmKElBVklFZGl0U3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkN1dChJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5Db3B5KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSBwU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGxTdGFydCxMT05HIGxFbmQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DbG9uZShJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFWSVNUUkVBTSpwcFJlc3VsdCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblNldEluZm8oSUFWSUVkaXRTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBVklTVFJFQU1JTkZPVyBhc2ksTE9ORyBzaXplKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSUVkaXRTdHJlYW1WdGJsIGllZGl0c3RyZWFtID0gewogIElBVklFZGl0U3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUVkaXRTdHJlYW1fZm5BZGRSZWYsCiAgSUFWSUVkaXRTdHJlYW1fZm5SZWxlYXNlLAogIElBVklFZGl0U3RyZWFtX2ZuQ3V0LAogIElBVklFZGl0U3RyZWFtX2ZuQ29weSwKICBJQVZJRWRpdFN0cmVhbV9mblBhc3RlLAogIElBVklFZGl0U3RyZWFtX2ZuQ2xvbmUsCiAgSUFWSUVkaXRTdHJlYW1fZm5TZXRJbmZvCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLExPTkcqYnl0ZXNyZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcHdyaXR0ZW4sTE9ORypieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGllZGl0c3Rhc3QgPSB7CiAgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZiwKICBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5JbmZvLAogIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkLAogIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZihJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsTFBWT0lEKnBwaW1wbCk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElFZGl0U3RyZWFtSW50ZXJuYWxWdGJsIGllZGl0c3RyZWFtaW50ZXJuYWwgPSB7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblF1ZXJ5SW50ZXJmYWNlLAogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5BZGRSZWYsCiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblJlbGVhc2UsCiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSUVkaXRTdHJlYW1JbXBsIElBVklFZGl0U3RyZWFtSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JRWRpdEFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklFZGl0U3RyZWFtSW1wbCAqcGFlOwp9IElFZGl0QVZJU3RyZWFtSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JRWRpdFN0cmVhbUludGVybmFsSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJRWRpdFN0cmVhbUludGVybmFsVnRibCAqbHBWdGJsOwoKICAvKiBJRWRpdFN0cmVhbUludGVybmFsIHN0dWZmICovCiAgSUFWSUVkaXRTdHJlYW1JbXBsICpwYWU7Cn0gSUVkaXRTdHJlYW1JbnRlcm5hbEltcGw7CgpzdHJ1Y3QgX0lBVklFZGl0U3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJRWRpdFN0cmVhbVZ0YmwgKmxwVnRibDsKICBMT05HICByZWY7CgogIC8qIElBVklFZGl0U3RyZWFtIHN0dWZmICovCiAgSUVkaXRBVklTdHJlYW1JbXBsICAgICAgaUFWSVN0cmVhbTsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCBpRWRpdFN0cmVhbUludGVybmFsOwoKICBBVklTVFJFQU1JTkZPVyAgICAgICBzSW5mbzsKCiAgRWRpdFN0cmVhbVRhYmxlICAgICAqcFN0cmVhbXM7CiAgRFdPUkQgICAgICAgICAgICAgICAgblN0cmVhbXM7ICAgLyogY3VycmVudCBmaWxsIGxldmVsIG9mIHBTdHJlYW1zIHRhYmxlICovCiAgRFdPUkQgICAgICAgICAgICAgICAgblRhYmxlU2l6ZTsgLyogc2l6ZSBvZiBwU3RyZWFtcyB0YWJsZSAqLwoKICBCT09MICAgICAgICAgICAgICAgICBiRGVjb21wcmVzczsKICBQQVZJU1RSRUFNICAgICAgICAgICBwQ3VyU3RyZWFtOwogIFBHRVRGUkFNRSAgICAgICAgICAgIHBnOyAgICAgICAgIC8qIElHZXRGcmFtZSBmb3IgcEN1clN0cmVhbSAqLwogIExQQklUTUFQSU5GT0hFQURFUiAgIGxwRnJhbWU7ICAgIC8qIGZyYW1lIG9mIHBDdXJTdHJlYW0gKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KClBBVklFRElUU1RSRUFNIEFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKnBlZGl0ID0gTlVMTDsKCiAgcGVkaXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklFZGl0U3RyZWFtSW1wbCkpOwogIGlmIChwZWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIHBlZGl0LT5scFZ0YmwgICAgICAgICAgICA9ICZpZWRpdHN0cmVhbTsKICBwZWRpdC0+aUFWSVN0cmVhbS5scFZ0YmwgPSAmaWVkaXRzdGFzdDsKICBwZWRpdC0+aUFWSVN0cmVhbS5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5scFZ0YmwgPSAmaWVkaXRzdHJlYW1pbnRlcm5hbDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+cmVmID0gMTsKCiAgSUFWSVN0cmVhbV9DcmVhdGUoKFBBVklTVFJFQU0pJnBlZGl0LT5pQVZJU3RyZWFtLChMUEFSQU0pcHN0cmVhbSwwKTsKCiAgcmV0dXJuIChQQVZJRURJVFNUUkVBTSlwZWRpdDsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMsCgkJCQkJIERXT1JEIHBvcyxQQVZJU1RSRUFNICpwcFN0cmVhbSwKCQkJCQkgRFdPUkQqIHN0cmVhbVBvcywKCQkJCQkgRFdPUkQqIHN0cmVhbU5yLEJPT0wgYkZpbmRTYW1wbGUpCnsKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCV1LCVwLCVwLCVwLCVkKVxuIixUaGlzLHBvcyxwcFN0cmVhbSxzdHJlYW1Qb3MsCiAgICAgICAgc3RyZWFtTnIsYkZpbmRTYW1wbGUpOwoKICBpZiAocG9zIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIHBvcyAtPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5uU3RyZWFtczsgbisrKSB7CiAgICBpZiAocG9zIDwgVGhpcy0+cFN0cmVhbXNbbl0uZHdMZW5ndGgpIHsKICAgICAgKnBwU3RyZWFtICA9IFRoaXMtPnBTdHJlYW1zW25dLnBTdHJlYW07CiAgICAgICpzdHJlYW1Qb3MgPSBUaGlzLT5wU3RyZWFtc1tuXS5kd1N0YXJ0ICsgcG9zOwogICAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgICAqc3RyZWFtTnIgPSBuOwoKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0KICAgIHBvcyAtPSBUaGlzLT5wU3RyZWFtc1tuXS5kd0xlbmd0aDsKICB9CiAgaWYgKHBvcyA9PSAwICYmIGJGaW5kU2FtcGxlKSB7CiAgICAqcHBTdHJlYW0gID0gVGhpcy0+cFN0cmVhbXNbLS1uXS5wU3RyZWFtOwogICAgKnN0cmVhbVBvcyA9IEVkaXRTdHJlYW1FbmQoVGhpcywgbik7CiAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgKnN0cmVhbU5yID0gbjsKCiAgICBUUkFDRSgiIC0tIHBvcz0wICYmIGI9MSAtPiAoJXAsJXUsJXUpXG4iLCpwcFN0cmVhbSwgKnN0cmVhbVBvcywgbik7CiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICAqcHBTdHJlYW0gPSBOVUxMOwogICAgKnN0cmVhbVBvcyA9IDA7CiAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgKnN0cmVhbU5yID0gMDsKCiAgICBUUkFDRSgiIC0+IEVSUk9SIChOVUxMLDAsMClcbiIpOwogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICB9Cn0KCnN0YXRpYyBMUFZPSUQgQVZJRklMRV9SZWFkRnJhbWUoSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MpCnsKICBQR0VURlJBTUUgcGc7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLFRoaXMscHN0cmVhbSxwb3MpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIC8qIGlmIHN0cmVhbSBjaGFuZ2VzIG1ha2Ugc3VyZSB0aGF0IG9ubHkgcGFsZXR0ZSBjaGFuZ2VzICovCiAgaWYgKFRoaXMtPnBDdXJTdHJlYW0gIT0gcHN0cmVhbSkgewogICAgcGcgPSBBVklTdHJlYW1HZXRGcmFtZU9wZW4ocHN0cmVhbSwgTlVMTCk7CiAgICBpZiAocGcgPT0gTlVMTCkKICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAoVGhpcy0+cGcgIT0gTlVMTCkgewogICAgICBpZiAoSUdldEZyYW1lX1NldEZvcm1hdChwZywgVGhpcy0+bHBGcmFtZSwgTlVMTCwgMCwgMCwgLTEsIC0xKSkgewogICAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UocGcpOwogICAgICAgIEVSUigiOiBJR2V0RnJhbWVfU2V0Rm9ybWF0IGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgIH0KICAgICAgQVZJU3RyZWFtR2V0RnJhbWVDbG9zZShUaGlzLT5wZyk7CiAgICB9CiAgICBUaGlzLT5wZyAgICAgICAgID0gcGc7CiAgICBUaGlzLT5wQ3VyU3RyZWFtID0gcHN0cmVhbTsKICB9CgogIC8qIG5vdyBnZXQgdGhlIGRlY29tcHJlc3NlZCBmcmFtZSAqLwogIFRoaXMtPmxwRnJhbWUgPSBBVklTdHJlYW1HZXRGcmFtZShUaGlzLT5wZywgcG9zKTsKICBpZiAoVGhpcy0+bHBGcmFtZSAhPSBOVUxMKQogICAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+bHBGcmFtZS0+YmlTaXplSW1hZ2U7CgogIHJldHVybiBUaGlzLT5scEZyYW1lOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1JlbW92ZVN0cmVhbShJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMsIERXT1JEIG5yKQp7CiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KG5yIDwgVGhpcy0+blN0cmVhbXMpOwoKICAvKiByZW1vdmUgcGFydCBuciAqLwogIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtc1tucl0ucFN0cmVhbSk7CiAgVGhpcy0+blN0cmVhbXMtLTsKICBpZiAoVGhpcy0+blN0cmVhbXMgLSBuciA+IDApIHsKICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBuciwgVGhpcy0+cFN0cmVhbXMgKyBuciArIDEsCiAgICAgICAgICAgIChUaGlzLT5uU3RyZWFtcyAtIG5yKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICB9CiAgVGhpcy0+cFN0cmVhbXNbVGhpcy0+blN0cmVhbXNdLnBTdHJlYW0gID0gTlVMTDsKICBUaGlzLT5wU3RyZWFtc1tUaGlzLT5uU3RyZWFtc10uZHdTdGFydCAgPSAwOwogIFRoaXMtPnBTdHJlYW1zW1RoaXMtPm5TdHJlYW1zXS5kd0xlbmd0aCA9IDA7CgogIC8qIHRyeSB0byBtZXJnZSB0aGUgcGFydCBiZWZvcmUgdGhlIGRlbGV0ZWQgb25lIGFuZCB0aGUgb25lIGFmdGVyIGl0ICovCiAgaWYgKDAgPCBuciAmJiAwIDwgVGhpcy0+blN0cmVhbXMgJiYKICAgICAgVGhpcy0+cFN0cmVhbXNbbnIgLSAxXS5wU3RyZWFtID09IFRoaXMtPnBTdHJlYW1zW25yXS5wU3RyZWFtKSB7CiAgICBpZiAoRWRpdFN0cmVhbUVuZChUaGlzLCBuciAtIDEpID09IFRoaXMtPnBTdHJlYW1zW25yXS5kd1N0YXJ0KSB7CiAgICAgIFRoaXMtPnBTdHJlYW1zW25yIC0gMV0uZHdMZW5ndGggKz0gVGhpcy0+cFN0cmVhbXNbbnJdLmR3TGVuZ3RoOwogICAgICByZXR1cm4gQVZJRklMRV9SZW1vdmVTdHJlYW0oVGhpcywgbnIpOwogICAgfQogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEJPT0wgQVZJRklMRV9Gb3JtYXRzRXF1YWwoUEFWSVNUUkVBTSBhdmkxLCBQQVZJU1RSRUFNIGF2aTIpCnsKICBMUFZPSUQgZm10MSA9IE5VTEwsIGZtdDIgPSBOVUxMOwogIExPTkcgc2l6ZTEsIHNpemUyLCBzdGFydDEsIHN0YXJ0MjsKICBCT09MIHN0YXR1cyA9IEZBTFNFOwoKICBhc3NlcnQoYXZpMSAhPSBOVUxMICYmIGF2aTIgIT0gTlVMTCk7CgogIC8qIGdldCBzdHJlYW0gc3RhcnRzIGFuZCBjaGVjayBmb3JtYXQgc2l6ZXMgKi8KICBzdGFydDEgPSBBVklTdHJlYW1TdGFydChhdmkxKTsKICBzdGFydDIgPSBBVklTdHJlYW1TdGFydChhdmkyKTsKICBpZiAoRkFJTEVEKEFWSVN0cmVhbUZvcm1hdFNpemUoYXZpMSwgc3RhcnQxLCAmc2l6ZTEpKSkKICAgIHJldHVybiBGQUxTRTsKICBpZiAoRkFJTEVEKEFWSVN0cmVhbUZvcm1hdFNpemUoYXZpMiwgc3RhcnQyLCAmc2l6ZTIpKSkKICAgIHJldHVybiBGQUxTRTsKICBpZiAoc2l6ZTEgIT0gc2l6ZTIpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIHNpemVzIG1hdGNoLCBub3cgZ2V0IGZvcm1hdHMgYW5kIGNvbXBhcmUgdGhlbSAqLwogIGZtdDEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZTEpOwogIGlmIChmbXQxID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KGF2aTEsIHN0YXJ0MSwgZm10MSwgJnNpemUxKSkpIHsKICAgIGZtdDIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZTEpOwogICAgaWYgKGZtdDIgIT0gTlVMTCkgewogICAgICBpZiAoU1VDQ0VFREVEKEFWSVN0cmVhbVJlYWRGb3JtYXQoYXZpMiwgc3RhcnQyLCBmbXQyLCAmc2l6ZTEpKSkKICAgICAgICBzdGF0dXMgPSAobWVtY21wKGZtdDEsIGZtdDIsIHNpemUxKSA9PSAwKTsKICAgIH0KICB9CgogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGZtdDIpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGZtdDEpOwoKICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJRWRpdFN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmVmaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklFZGl0U3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gaWZhY2U7CiAgICBJQVZJRWRpdFN0cmVhbV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmlBVklTdHJlYW07CiAgICBJQVZJRWRpdFN0cmVhbV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JRWRpdFN0cmVhbUludGVybmFsLCByZWZpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmlFZGl0U3RyZWFtSW50ZXJuYWw7CiAgICBJQVZJRWRpdFN0cmVhbV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0KCiAgcmV0dXJuIE9MRV9FX0VOVU1fTk9NT1JFOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5BZGRSZWYoSUFWSUVkaXRTdHJlYW0qaWZhY2UpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVkXG4iLCBpZmFjZSwgcmVmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBEV09SRCBpOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlZFxuIiwgaWZhY2UsIHJlZik7CgogIGlmICghcmVmKSB7CiAgICAvKiByZWxlYXNlIG1lbW9yeSAqLwogICAgaWYgKFRoaXMtPnBnICE9IE5VTEwpCiAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoVGhpcy0+cGcpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zICE9IE5VTEwpIHsKICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPm5TdHJlYW1zOyBpKyspIHsKICAgICAgICBpZiAoVGhpcy0+cFN0cmVhbXNbaV0ucFN0cmVhbSAhPSBOVUxMKQogICAgICAgICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW1zW2ldLnBTdHJlYW0pOwogICAgICB9CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBTdHJlYW1zKTsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DdXQoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIFBBVklTVFJFQU0gc3RyZWFtOwogIERXT1JEICAgICAgc3RhcnQsIGxlbiwgc3RyZWFtUG9zLCBzdHJlYW1OcjsKICBIUkVTVUxUICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ICE9IE5VTEwpCiAgICAqcHBSZXN1bHQgPSBOVUxMOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCAqcGxTdGFydCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBpZiBhc2tlZCBmb3IgY3V0IHBhcnQgY29weSBpdCBiZWZvcmUgZGVsZXRpbmcgKi8KICBpZiAocHBSZXN1bHQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9Db3B5KGlmYWNlLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIHN0YXJ0ID0gKnBsU3RhcnQ7CiAgbGVuICAgPSAqcGxMZW5ndGg7CgogIC8qIG5vdyBkZWxldGUgdGhlIHJlcXVlc3RlZCBwYXJ0ICovCiAgd2hpbGUgKGxlbiA+IDApIHsKICAgIGhyID0gQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBzdGFydCwgJnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtUG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgPT0gc3RyZWFtUG9zKSB7CiAgICAgIC8qIGRlbGV0aW5nIGZyb20gc3RhcnQgb2YgcGFydCAqLwogICAgICBpZiAobGVuIDwgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoKSB7CiAgICAgICAgc3RhcnQgKz0gbGVuOwogICAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICArPSBsZW47CiAgICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoIC09IGxlbjsKICAgICAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBsZW47CiAgICAgICAgbGVuID0gMDsKCiAgICAgICAgLyogd2UgbXVzdCByZXR1cm4gZGVjb21wcmVzc2VkIGRhdGEgbm93ICovCiAgICAgICAgVGhpcy0+YkRlY29tcHJlc3MgPSBUUlVFOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIGRlbGV0aW5nIGhvbGUgcGFydCAqLwogICAgICAgIGxlbiAtPSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CiAgICAgICAgQVZJRklMRV9SZW1vdmVTdHJlYW0oVGhpcyxzdHJlYW1Ocik7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgPD0gc3RyZWFtUG9zICsgbGVuKSB7CiAgICAgIC8qIGRlbGV0aW5nIGF0IGVuZCBvZiBhIHBhcnQgKi8KICAgICAgRFdPUkQgY291bnQgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIHN0cmVhbVBvczsKICAgICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gY291bnQ7CiAgICAgIGxlbiAgICAgICAgICAgICAgICAgIC09IGNvdW50OwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQogICAgICAgIHN0cmVhbVBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgfSBlbHNlIHsKICAgICAgLyogc3BsaXR0aW5nICovCiAgICAgIGlmIChUaGlzLT5uU3RyZWFtcyArIDEgPj0gVGhpcy0+blRhYmxlU2l6ZSkgewogICAgICAgIFRoaXMtPnBTdHJlYW1zID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+cFN0cmVhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+blRhYmxlU2l6ZSArIDMyKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgICAgICBpZiAoVGhpcy0+cFN0cmVhbXMgPT0gTlVMTCkKICAgICAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICAgIFRoaXMtPm5UYWJsZVNpemUgKz0gMzI7CiAgICAgIH0KICAgICAgbWVtbW92ZShUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yICsgMSwgVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciwKICAgICAgICAgICAgICAoVGhpcy0+blN0cmVhbXMgLSBzdHJlYW1OcikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICAgIFRoaXMtPm5TdHJlYW1zKys7CgogICAgICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLnBTdHJlYW0pOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLmR3U3RhcnQgID0gc3RyZWFtUG9zICsgbGVuOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLmR3TGVuZ3RoID0KICAgICAgICBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgMV0uZHdTdGFydDsKCiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCA9CiAgICAgICAgc3RyZWFtUG9zIC0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQ7CiAgICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC09IGxlbjsKICAgICAgbGVuID0gMDsKICAgIH0KICB9CgogIFRoaXMtPnNJbmZvLmR3RWRpdENvdW50Kys7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkNvcHkoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSpwcFJlc3VsdCkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBJQVZJRWRpdFN0cmVhbUltcGwqIHBFZGl0OwogIEhSRVNVTFQgaHI7CiAgTE9ORyBzdGFydCA9IDA7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLGlmYWNlLHBsU3RhcnQscGxMZW5ndGgscHBSZXN1bHQpOwoKICBpZiAocHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgKnBwUmVzdWx0ID0gTlVMTDsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8IHBsTGVuZ3RoID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwIHx8ICpwbExlbmd0aCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBjaGVjayBib3VuZHMgKi8KICBpZiAoKihMUERXT1JEKXBsTGVuZ3RoID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICAqKExQRFdPUkQpcGxMZW5ndGggPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBpZiAoKihMUERXT1JEKXBsU3RhcnQgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KSB7CiAgICAqKExQRFdPUkQpcGxMZW5ndGggLT0gVGhpcy0+c0luZm8uZHdTdGFydCAtICooTFBEV09SRClwbFN0YXJ0OwogICAgKihMUERXT1JEKXBsU3RhcnQgICA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBpZiAoKnBsTGVuZ3RoIDwgMCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICB9CiAgaWYgKCooTFBEV09SRClwbFN0YXJ0ICsgKihMUERXT1JEKXBsTGVuZ3RoID4gVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgKihMUERXT1JEKXBsTGVuZ3RoID0gVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0KICAgICAgKihMUERXT1JEKXBsU3RhcnQ7CgogIHBFZGl0ID0gKElBVklFZGl0U3RyZWFtSW1wbCopQVZJRklMRV9DcmVhdGVFZGl0U3RyZWFtKE5VTEwpOwogIGlmIChwRWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGhyID0gSUFWSUVkaXRTdHJlYW1fUGFzdGUoKFBBVklFRElUU1RSRUFNKXBFZGl0LCZzdGFydCxwbExlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCpwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKnBsU3RhcnQgKyAqcGxMZW5ndGgpOwogICpwbFN0YXJ0ID0gc3RhcnQ7CiAgaWYgKEZBSUxFRChocikpCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKChQQVZJRURJVFNUUkVBTSlwRWRpdCk7CiAgZWxzZQogICAgKnBwUmVzdWx0ID0gKFBBVklTVFJFQU0pJnBFZGl0LT5pQVZJU3RyZWFtOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblBhc3RlKElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNIHBTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgbFN0YXJ0LExPTkcgbExlbmd0aCkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBBVklTVFJFQU1JTkZPVyAgICAgIHNyY0luZm87CiAgSUVkaXRTdHJlYW1JbnRlcm5hbCpwSW50ZXJuYWwgPSBOVUxMOwogIElBVklFZGl0U3RyZWFtSW1wbCAqcEVkaXQgPSBOVUxMOwogIFBBVklTVFJFQU0gICAgICAgICAgcFN0cmVhbTsKICBEV09SRCAgICAgICAgICAgICAgIHN0YXJ0UG9zLCBlbmRQb3MsIHN0cmVhbU5yLCBuU3RyZWFtczsKICBVTE9ORyAgICAgICAgICAgICAgIG47CgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJWQsJWQpXG4iLGlmYWNlLHBsU3RhcnQscGxMZW5ndGgsCglwU291cmNlLGxTdGFydCxsTGVuZ3RoKTsKCiAgaWYgKHBTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKnBsU3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOyAvKiBDYW4ndCBwYXN0ZSB3aXRoIGhvbGVzICovCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocFNvdXJjZSwgJnNyY0luZm8sIHNpemVvZihzcmNJbmZvKSkpKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICBpZiAobFN0YXJ0IDwgc3JjSW5mby5kd1N0YXJ0IHx8IGxTdGFydCA+PSBzcmNJbmZvLmR3U3RhcnQgKyBzcmNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSAwKSB7CiAgICAvKiBUaGlzIHN0cmVhbSBpcyBlbXB0eSAqLwogICAgSUFWSVN0cmVhbV9JbmZvKHBTb3VyY2UsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ICA9ICpwbFN0YXJ0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSAwOwogIH0KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzcmNJbmZvLmZjY1R5cGUpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBkaWZmZXJlbnQgc3RyZWFtIHR5cGVzICovCiAgaWYgKGxMZW5ndGggPT0gLTEpIC8qIENvcHkgdGhlIGhvbGUgc3RyZWFtICovCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd0xlbmd0aDsKICBpZiAobFN0YXJ0ICsgbExlbmd0aCA+IHNyY0luZm8uZHdTdGFydCArIHNyY0luZm8uZHdMZW5ndGgpCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd1N0YXJ0ICsgc3JjSW5mby5kd0xlbmd0aCAtIGxTdGFydDsKICBpZiAobExlbmd0aCArICpwbFN0YXJ0ID49IDB4ODAwMDAwMDApCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogc3RyZWFtdHlwZSBzcGVjaWZpYyB0ZXN0cyAqLwogIGlmIChzcmNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICBMT05HIHNpemU7CgogICAgc2l6ZSA9IHNyY0luZm8ucmNGcmFtZS5yaWdodCAtIHNyY0luZm8ucmNGcmFtZS5sZWZ0OwogICAgaWYgKHNpemUgIT0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogRklYTUU6IENhbid0IEdldEZyYW1lIGNvbnZlcnQgaXQ/ICovCiAgICBzaXplID0gc3JjSW5mby5yY0ZyYW1lLmJvdHRvbSAtIHNyY0luZm8ucmNGcmFtZS50b3A7CiAgICBpZiAoc2l6ZSAhPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBGSVhNRTogQ2FuJ3QgR2V0RnJhbWUgY29udmVydCBpdD8gKi8KICB9IGVsc2UgaWYgKHNyY0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKICAgIGlmICghIEFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UgewogICAgLyogRklYTUU6IHN0cmVhbXR5cGVNSURJIGFuZCBzdHJlYW10eXBlVEVYVCAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIHRyeSB0byBnZXQgYW4gSUVkaXRTdHJlYW1JbnRlcm5hbCBpbnRlcmZhY2UgKi8KICBpZiAoU1VDQ0VFREVEKElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFNvdXJjZSwgJklJRF9JRWRpdFN0cmVhbUludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKikmcEludGVybmFsKSkpIHsKICAgIHBJbnRlcm5hbC0+bHBWdGJsLT5HZXRFZGl0U3RyZWFtSW1wbChwSW50ZXJuYWwsIChMUFZPSUQqKSZwRWRpdCk7CiAgICBwSW50ZXJuYWwtPmxwVnRibC0+UmVsZWFzZShwSW50ZXJuYWwpOwogIH0KCiAgLyogZm9yIHZpZGVvIG11c3QgY2hlY2sgZm9yIGNoYW5nZSBvZiBmb3JtYXQgKi8KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAgIC8qIE5lZWQgdG8gZGVjb21wcmVzcyBpZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG1hdGNoZXM6CiAgICAgICAqICAtIHBTb3VyY2UgaXMgYW4gZWRpdGFibGUgc3RyZWFtIHdoaWNoIGRlY29tcHJlc3NlcwogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiBwU291cmNlIGlzbid0IGxTdGFydAogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiB0aGlzIHN0cmVhbSBpc24ndCAqcGxTdGFydAogICAgICAgKiAgLSB0aGUgZm9ybWF0IG9mIHBTb3VyY2UgZG9lc24ndCBtYXRjaCB0aGlzIG9uZQogICAgICAgKi8KICAgICAgaWYgKChwRWRpdCAhPSBOVUxMICYmIHBFZGl0LT5iRGVjb21wcmVzcykgfHwKCSAgQVZJU3RyZWFtTmVhcmVzdEtleUZyYW1lKHBTb3VyY2UsIGxTdGFydCkgIT0gbFN0YXJ0IHx8CgkgIEFWSVN0cmVhbU5lYXJlc3RLZXlGcmFtZSgoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwgKnBsU3RhcnQpICE9ICpwbFN0YXJ0IHx8CgkgIChUaGlzLT5uU3RyZWFtcyA+IDAgJiYgIUFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkpIHsKCS8qIFVzZSBmaXJzdCBzdHJlYW0gcGFydCB0byBnZXQgZm9ybWF0IHRvIGNvbnZlcnQgZXZlcnl0aGluZyB0byAqLwoJQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgVGhpcy0+cFN0cmVhbXNbMF0ucFN0cmVhbSwKCQkJICBUaGlzLT5wU3RyZWFtc1swXS5kd1N0YXJ0KTsKCgkvKiBDaGVjayBpZiB3ZSBjb3VsZCBjb252ZXJ0IHRoZSBzb3VyY2Ugc3RyZWFtcyB0byB0aGUgZGVzaXJlZCBmb3JtYXQuLi4gKi8KCWlmIChwRWRpdCAhPSBOVUxMKSB7CgkgIGlmIChGQUlMRUQoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJCQkgICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIFRSVUUpKSkKCSAgICByZXR1cm4gQVZJRVJSX0lOVEVSTkFMOwoJICBmb3IgKG4gPSBsU3RhcnQ7IG4gPCBsU3RhcnQgKyBsTGVuZ3RoOyBzdHJlYW1OcisrKSB7CgkgICAgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0ucFN0cmVhbSwgc3RhcnRQb3MpID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCSAgICBzdGFydFBvcyA9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKCSAgICBuICs9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CgkgIH0KCX0gZWxzZSBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcFNvdXJjZSwgbFN0YXJ0KSA9PSBOVUxMKQoJICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCglUaGlzLT5iRGVjb21wcmVzcyAgICAgID0gVFJVRTsKCVRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgPSAwOwogICAgICB9CiAgICB9IGVsc2UgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBTb3VyY2UsIGxTdGFydCkgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7IC8qIENhbid0IGNvbnZlcnQgc291cmNlIHRvIG93biBmb3JtYXQgKi8KICB9IC8qIEZJWE1FOiBzb21ldGhpbmcgc3BlY2lhbCBmb3IgdGhlIG90aGVyIGZvcm1hdHM/ICovCgogIC8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGVub3VnaCBtZW1vcnkgZm9yIHBhcnRzICovCiAgaWYgKHBFZGl0ICE9IE5VTEwpIHsKICAgIERXT1JEIG5MYXN0U3RyZWFtOwoKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCArIGxMZW5ndGgsICZwU3RyZWFtLAoJCQkgICAgICAmZW5kUG9zLCAmbkxhc3RTdHJlYW0sIFRSVUUpOwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChuTGFzdFN0cmVhbSA9PSBzdHJlYW1OcikKICAgICAgbkxhc3RTdHJlYW0rKzsKCiAgICBuU3RyZWFtcyA9IG5MYXN0U3RyZWFtIC0gc3RyZWFtTnI7CiAgfSBlbHNlIAogICAgblN0cmVhbXMgPSAxOwogIGlmIChUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMSA+IFRoaXMtPm5UYWJsZVNpemUpIHsKICAgIG4gPSBUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMzM7CgogICAgVGhpcy0+cFN0cmVhbXMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5wU3RyZWFtcywgbiAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPm5UYWJsZVNpemUgPSBuOwogIH0KCiAgaWYgKHBsTGVuZ3RoICE9IE5VTEwpCiAgICAqcGxMZW5ndGggPSBsTGVuZ3RoOwoKICAvKiBub3cgZG8gdGhlIHJlYWwgd29yayAqLwogIGlmIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPiAqcGxTdGFydCkgewogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCAqcGxTdGFydCwgJnBTdHJlYW0sCgkJCSAgICAgICZzdGFydFBvcywgJnN0cmVhbU5yLCBGQUxTRSk7CiAgICBpZiAoc3RhcnRQb3MgIT0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQpIHsKICAgICAgLyogc3BsaXQgc3RyZWFtIHN0cmVhbU5yIGF0IHN0YXJ0UG9zICovCiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIG5TdHJlYW1zICsgMSwKCSAgICAgIFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsCgkgICAgICAoVGhpcy0+blN0cmVhbXMgKyBuU3RyZWFtcyAtIHN0cmVhbU5yICsgMSkgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CgogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDJdLmR3TGVuZ3RoID0KCUVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIgKyAyKSAtIHN0YXJ0UG9zOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDJdLmR3U3RhcnQgPSBzdGFydFBvczsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KCXN0YXJ0UG9zIC0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQ7CiAgICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5wU3RyZWFtKTsKICAgICAgc3RyZWFtTnIrKzsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGluc2VydCBiZWZvcmUgc3RyZWFtIGF0IHN0cmVhbU5yICovCiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIG5TdHJlYW1zLCBUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yLAoJICAgICAgKFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgLSBzdHJlYW1OcikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICB9CiAgfSBlbHNlIC8qIGFwcGVuZCB0aGUgc3RyZWFtcyAqLwogICAgc3RyZWFtTnIgPSBUaGlzLT5uU3RyZWFtczsKCiAgaWYgKHBFZGl0ICE9IE5VTEwpIHsKICAgIC8qIGluc2VydCB0aGUgcGFydHMgb2YgdGhlIGVkaXRhYmxlIHN0cmVhbSBpbnN0ZWFkIG9mIGl0c2VsZiAqLwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0ICsgbExlbmd0aCwgJnBTdHJlYW0sCgkJCSAgICAgICZlbmRQb3MsIE5VTEwsIEZBTFNFKTsKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCwgJnBTdHJlYW0sICZzdGFydFBvcywgJm4sIEZBTFNFKTsKCiAgICBtZW1jcHkoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciwgcEVkaXQtPnBTdHJlYW1zICsgbiwKCSAgIG5TdHJlYW1zICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0IDwgc3RhcnRQb3MpIHsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KCUVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIC0gc3RhcnRQb3M7CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICA9IHN0YXJ0UG9zOwogICAgfQogICAgaWYgKGVuZFBvcyA8IEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIgKyBuU3RyZWFtcykpCiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgblN0cmVhbXNdLmR3TGVuZ3RoID0KCWVuZFBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgblN0cmVhbXNdLmR3U3RhcnQ7CiAgfSBlbHNlIHsKICAgIC8qIGEgc2ltcGxlIHN0cmVhbSAqLwogICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLnBTdHJlYW0gID0gcFNvdXJjZTsKICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICA9IGxTdGFydDsKICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCA9IGxMZW5ndGg7CiAgfQoKICBmb3IgKG4gPSAwOyBuIDwgblN0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyBuXS5wU3RyZWFtKTsKICAgIGlmICgwIDwgc3RyZWFtTnIgKyBuICYmCglUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIG4gLSAxXS5wU3RyZWFtICE9IFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgbl0ucFN0cmVhbSkgewogICAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKICAgICAgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCsrOwogICAgfQogIH0KICBUaGlzLT5zSW5mby5kd0VkaXRDb3VudCsrOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICs9IGxMZW5ndGg7CiAgVGhpcy0+blN0cmVhbXMgKz0gblN0cmVhbXM7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkNsb25lKElBVklFZGl0U3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIElBVklFZGl0U3RyZWFtSW1wbCogcEVkaXQ7CiAgRFdPUkQgaTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsaWZhY2UscHBSZXN1bHQpOwoKICBpZiAocHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgKnBwUmVzdWx0ID0gTlVMTDsKCiAgcEVkaXQgPSAoSUFWSUVkaXRTdHJlYW1JbXBsKilBVklGSUxFX0NyZWF0ZUVkaXRTdHJlYW0oTlVMTCk7CiAgaWYgKHBFZGl0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBpZiAoVGhpcy0+blN0cmVhbXMgPiBwRWRpdC0+blRhYmxlU2l6ZSkgewogICAgcEVkaXQtPnBTdHJlYW1zID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgcEVkaXQtPnBTdHJlYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+blN0cmVhbXMgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICBpZiAocEVkaXQtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgcEVkaXQtPm5UYWJsZVNpemUgPSBUaGlzLT5uU3RyZWFtczsKICB9CiAgcEVkaXQtPm5TdHJlYW1zID0gVGhpcy0+blN0cmVhbXM7CiAgbWVtY3B5KHBFZGl0LT5wU3RyZWFtcywgVGhpcy0+cFN0cmVhbXMsCiAgICAgICAgIFRoaXMtPm5TdHJlYW1zICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogIG1lbWNweSgmcEVkaXQtPnNJbmZvLCZUaGlzLT5zSW5mbyxzaXplb2YoVGhpcy0+c0luZm8pKTsKICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+blN0cmVhbXM7IGkrKykgewogICAgaWYgKHBFZGl0LT5wU3RyZWFtc1tpXS5wU3RyZWFtICE9IE5VTEwpCiAgICAgIElBVklTdHJlYW1fQWRkUmVmKHBFZGl0LT5wU3RyZWFtc1tpXS5wU3RyZWFtKTsKICB9CgogICpwcFJlc3VsdCA9IChQQVZJU1RSRUFNKSZwRWRpdC0+aUFWSVN0cmVhbTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuU2V0SW5mbyhJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSxMT05HIHNpemUpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLGlmYWNlLGFzaSxzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChhc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgIT0gc2l6ZW9mKEFWSVNUUkVBTUlORk9XKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKICBpZiAoYXNpLT5kd1NjYWxlID09IDAgfHwgYXNpLT5kd1JhdGUgPT0gMCB8fCAoTE9ORylhc2ktPmR3UXVhbGl0eSA8IC0xIHx8CiAgICAgIGFzaS0+ZHdRdWFsaXR5ID4gSUNRVUFMSVRZX0hJR0gpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICBUaGlzLT5zSW5mby53TGFuZ3VhZ2UgPSBhc2ktPndMYW5ndWFnZTsKICBUaGlzLT5zSW5mby53UHJpb3JpdHkgPSBhc2ktPndQcmlvcml0eTsKICBUaGlzLT5zSW5mby5kd1N0YXJ0ICAgPSBhc2ktPmR3U3RhcnQ7CiAgaWYgKGFzaS0+ZHdSYXRlICE9IDApCiAgICBUaGlzLT5zSW5mby5kd1JhdGUgID0gYXNpLT5kd1JhdGU7CiAgaWYgKGFzaS0+ZHdTY2FsZSAhPSAwKQogICAgVGhpcy0+c0luZm8uZHdTY2FsZSA9IGFzaS0+ZHdTY2FsZTsKICBpZiAoYXNpLT5kd1F1YWxpdHkgPD0gSUNRVUFMSVRZX0hJR0gpCiAgICBUaGlzLT5zSW5mby5kd1F1YWxpdHkgPSBJQ1FVQUxJVFlfSElHSDsKICBDb3B5UmVjdCgmVGhpcy0+c0luZm8ucmNGcmFtZSwgJmFzaS0+cmNGcmFtZSk7CiAgbWVtY3B5KCZUaGlzLT5zSW5mby5zek5hbWUsICZhc2ktPnN6TmFtZSwgc2l6ZW9mKGFzaS0+c3pOYW1lKSk7CiAgVGhpcy0+c0luZm8uZHdFZGl0Q291bnQrKzsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUscmVmaWlkLG9iaik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fQWRkUmVmKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKmlmYWNlKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUmVsZWFzZSgoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWU7CgogIGlmIChsUGFyYW0yICE9IDApCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICBpZiAoVGhpcy0+cFN0cmVhbXMgPT0gTlVMTCkgewogICAgVGhpcy0+cFN0cmVhbXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgMjU2ICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+blRhYmxlU2l6ZSA9IDI1NjsKICB9CgogIGlmIChsUGFyYW0xICE9IDApIHsKICAgIElBVklTdHJlYW1fSW5mbygoUEFWSVNUUkVBTSlsUGFyYW0xLCAmVGhpcy0+c0luZm8sIHNpemVvZihUaGlzLT5zSW5mbykpOwogICAgSUFWSVN0cmVhbV9BZGRSZWYoKFBBVklTVFJFQU0pbFBhcmFtMSk7CiAgICBUaGlzLT5wU3RyZWFtc1swXS5wU3RyZWFtICA9IChQQVZJU1RSRUFNKWxQYXJhbTE7CiAgICBUaGlzLT5wU3RyZWFtc1swXS5kd1N0YXJ0ICA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBUaGlzLT5wU3RyZWFtc1swXS5kd0xlbmd0aCA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogICAgVGhpcy0+blN0cmVhbXMgPSAxOwogIH0KICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpCnsKICBJRWRpdEFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUVkaXRBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLGlmYWNlLHBzaSxzaXplKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgaWYgKHBzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGlmIChUaGlzLT5wYWUtPmJEZWNvbXByZXNzKQogICAgVGhpcy0+cGFlLT5zSW5mby5mY2NIYW5kbGVyID0gMDsKCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnBhZS0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnBhZS0+c0luZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5wYWUtPnNJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIExPTkcgICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgZmxhZ3MpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgUEFWSVNUUkVBTSBzdHJlYW07CiAgRFdPUkQgICAgICBzdHJlYW1Qb3MsIHN0cmVhbU5yOwoKICBUUkFDRSgiKCVwLCVkLDB4JTA4WClcbiIsaWZhY2UscG9zLGZsYWdzKTsKCiAgaWYgKGZsYWdzICYgRklORF9GUk9NX1NUQVJUKQogICAgcG9zID0gKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydDsKCiAgLyogb3V0c2lkZSBvZiBzdHJlYW0/ICovCiAgaWYgKHBvcyA8IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgfHwKICAgICAgKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCArIChMT05HKVRoaXMtPnNJbmZvLmR3TGVuZ3RoIDw9IHBvcykKICAgIHJldHVybiAtMTsKCiAgLyogbWFwIG91ciBwb3NpdGlvbiB0byBhIHN0cmVhbSBhbmQgcG9zaXRpb24gaW4gaXQgKi8KICBpZiAoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBwb3MsICZzdHJlYW0sICZzdHJlYW1Qb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0cmVhbU5yLCBUUlVFKSkKICAgIHJldHVybiAtMTsgLyogZG9lc24ndCBleGlzdCAqLwoKICBpZiAoVGhpcy0+YkRlY29tcHJlc3MpIHsKICAgIC8qIG9ubHkgb25lIHN0cmVhbSAtLSBmb3JtYXQgY2hhbmdlcyBvbmx5IGF0IHN0YXJ0ICovCiAgICBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkKICAgICAgcmV0dXJuIChmbGFncyAmIEZJTkRfTkVYVCA/IC0xIDogMCk7CgogICAgLyogRklYTUU6IG1hcCBwb3NpdGlvbnMgYmFjayB0byB1cyAqLwogICAgcmV0dXJuIElBVklTdHJlYW1fRmluZFNhbXBsZShzdHJlYW0sIHN0cmVhbVBvcywgZmxhZ3MpOwogIH0gZWxzZSB7CiAgICAvKiBhc3N1bWUgY2hhbmdlIG9mIGZvcm1hdCBldmVyeSBmcmFtZSAqLwogICAgcmV0dXJuIHBvczsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgZm9ybWF0LExPTkcqZm10c2l6ZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcyA9ICgoSUVkaXRBVklTdHJlYW1JbXBsKiBjb25zdClpZmFjZSktPnBhZTsKICBMUEJJVE1BUElORk9IRUFERVIgIGxwOwogIFBBVklTVFJFQU0gICAgICAgICAgc3RyZWFtOwogIERXT1JEICAgICAgICAgICAgICAgbjsKICBIUkVTVUxUICAgICAgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVkLCVwLCVwKVxuIixpZmFjZSxwb3MsZm9ybWF0LGZtdHNpemUpOwoKICBpZiAoZm10c2l6ZSA9PSBOVUxMIHx8IHBvcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQgfHwKICAgICAgVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDw9IHBvcykKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIGZpbmQgc3RyZWFtIGNvcnJlc3BvbmRpbmcgdG8gcG9zaXRpb24gKi8KICBociA9IEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgcG9zLCAmc3RyZWFtLCAmbiwgTlVMTCwgRkFMU0UpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBpZiAoISBUaGlzLT5iRGVjb21wcmVzcykKICAgIHJldHVybiBJQVZJU3RyZWFtX1JlYWRGb3JtYXQoc3RyZWFtLCBuLCBmb3JtYXQsIGZtdHNpemUpOwoKICBscCA9IChMUEJJVE1BUElORk9IRUFERVIpQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgc3RyZWFtLCBuKTsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgaWYgKGxwLT5iaUJpdENvdW50IDw9IDgpIHsKICAgIG4gID0gKGxwLT5iaUNsclVzZWQgPiAwID8gbHAtPmJpQ2xyVXNlZCA6IDEgPDwgbHAtPmJpQml0Q291bnQpOwogICAgbiAqPSBzaXplb2YoUkdCUVVBRCk7CiAgfSBlbHNlCiAgICBuID0gMDsKICBuICs9IGxwLT5iaVNpemU7CiAgCiAgbWVtY3B5KGZvcm1hdCwgbHAsIG1pbigoTE9ORyluLCAqZm10c2l6ZSkpOwogIGhyID0gKChMT05HKW4gPiAqZm10c2l6ZSA/IEFWSUVSUl9CVUZGRVJUT09TTUFMTCA6IEFWSUVSUl9PSyk7CiAgKmZtdHNpemUgPSBuOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVkLCVwLCVkKVxuIixpZmFjZSxwb3MsZm9ybWF0LGZvcm1hdHNpemUpOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGJ1ZmZlcnNpemUsTE9ORypieXRlc3JlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypzYW1wbGVzcmVhZCkKewogIElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcyA9ICgoSUVkaXRBVklTdHJlYW1JbXBsKiBjb25zdClpZmFjZSktPnBhZTsKICBQQVZJU1RSRUFNIHN0cmVhbTsKICBEV09SRCAgIHN0cmVhbVBvcywgc3RyZWFtTnI7CiAgTE9ORyAgICByZWFkQnl0ZXMsIHJlYWRTYW1wbGVzLCBjb3VudDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLCVwLCVwKSAtLSAweCUwOFhcbiIsaWZhY2Usc3RhcnQsc2FtcGxlcywKICAgICAgICBidWZmZXIsYnVmZmVyc2l6ZSxieXRlc3JlYWQsc2FtcGxlc3JlYWQsVGhpcy0+c0luZm8uZmNjVHlwZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gMDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IDA7CiAgaWYgKGJ1ZmZlcnNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwogIGlmICgoRFdPUkQpc3RhcnQgPCBUaGlzLT5zSW5mby5kd1N0YXJ0IHx8CiAgICAgIFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8IChEV09SRClzdGFydCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAvKiBhdWRpbyBsaWtlIGRhdGEgLS0gc2FtcGxlLWJhc2VkICovCiAgICBkbyB7CiAgICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgICAgcmV0dXJuIEFWSUVSUl9PSzsgLyogbm90aGluZyBhdCBhbGwgb3IgYWxyZWFkeSBkb25lICovCgogICAgICBpZiAoRkFJTEVEKEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgc3RhcnQsICZzdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtUG9zLCAmc3RyZWFtTnIsIEZBTFNFKSkpCiAgICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgICAgIC8qIGxpbWl0IHRvIGVuZCBvZiB0aGUgc3RyZWFtICovCiAgICAgIGNvdW50ID0gc2FtcGxlczsKICAgICAgaWYgKHN0cmVhbVBvcyArIGNvdW50ID4gRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikpCiAgICAgICAgY291bnQgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIHN0cmVhbVBvczsKCiAgICAgIGhyID0gSUFWSVN0cmVhbV9SZWFkKHN0cmVhbSwgc3RyZWFtUG9zLCBjb3VudCwgYnVmZmVyLCBidWZmZXJzaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVhZEJ5dGVzLCAmcmVhZFNhbXBsZXMpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgICByZXR1cm4gaHI7CiAgICAgIGlmIChyZWFkQnl0ZXMgPT0gMCAmJiByZWFkU2FtcGxlcyA9PSAwICYmIGNvdW50ICE9IDApCiAgICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsgLyogZm9yIGJhZCBzdHJlYW0gaW1wbGVtZW50YXRpb25zICovCgogICAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgICAqc2FtcGxlc3JlYWQgKz0gcmVhZFNhbXBsZXM7CiAgICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgICAqYnl0ZXNyZWFkICs9IHJlYWRCeXRlczsKICAgICAgaWYgKGJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgYnVmZmVyID0gKChMUEJZVEUpYnVmZmVyKStyZWFkQnl0ZXM7CiAgICAgICAgYnVmZmVyc2l6ZSAgICAgLT0gcmVhZEJ5dGVzOwogICAgICB9CiAgICAgIHN0YXJ0ICAgKz0gY291bnQ7CiAgICAgIHNhbXBsZXMgLT0gY291bnQ7CiAgICB9IHdoaWxlIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPiBzdGFydCk7CiAgfSBlbHNlIHsKICAgIC8qIHZpZGVvIGxpa2UgZGF0YSAtLSBmcmFtZS1iYXNlZCAqLwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwOwoKICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CgogICAgaWYgKEZBSUxFRChBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKFRoaXMsIHN0YXJ0LCAmc3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdHJlYW1Qb3MsICZzdHJlYW1OciwgRkFMU0UpKSkKICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgICBscCA9IEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHN0cmVhbSwgc3RyZWFtUG9zKTsKICAgIGlmIChscCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICAgIGlmIChidWZmZXIgIT0gTlVMTCkgewogICAgICAvKiBuZWVkIHNpemUgb2YgZm9ybWF0IHRvIHNraXAgKi8KICAgICAgaWYgKGxwLT5iaUJpdENvdW50IDw9IDgpIHsKICAgICAgICBjb3VudCAgPSBscC0+YmlDbHJVc2VkID4gMCA/IGxwLT5iaUNsclVzZWQgOiAxIDw8IGxwLT5iaUJpdENvdW50OwogICAgICAgIGNvdW50ICo9IHNpemVvZihSR0JRVUFEKTsKICAgICAgfSBlbHNlCiAgICAgICAgY291bnQgPSAwOwogICAgICBjb3VudCArPSBscC0+YmlTaXplOwoKICAgICAgaWYgKGJ1ZmZlcnNpemUgPCBscC0+YmlTaXplSW1hZ2UpCiAgICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICAgICAgbWVtY3B5KGJ1ZmZlciwgKExQQllURSlscCArIGNvdW50LCBscC0+YmlTaXplSW1hZ2UpOwogICAgfQoKICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IGxwLT5iaVNpemVJbWFnZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSAxOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXB3cml0dGVuLExPTkcqYnl0ZXN3cml0dGVuKQp7CiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwweCUwOFgsJXAsJXApXG4iLGlmYWNlLHN0YXJ0LHNhbXBsZXMsYnVmZmVyLAogICAgICAgIGJ1ZmZlcnNpemUsZmxhZ3Msc2FtcHdyaXR0ZW4sYnl0ZXN3cml0dGVuKTsKCiAgLyogYmUgc3VyZSByZXR1cm4gcGFyYW1ldGVycyBoYXZlIGNvcnJlY3QgdmFsdWVzICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVkLCVkKVxuIixpZmFjZSxzdGFydCxzYW1wbGVzKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX0N1dCgoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSwmc3RhcnQsJnNhbXBsZXMsTlVMTCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgbHAsTE9ORyAqbHByZWFkKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqIGNvbnN0KWlmYWNlKS0+cGFlOwogIERXT1JEIG47CgogIFRSQUNFKCIoJXAsMHglMDhYLCVwLCVwKVxuIixpZmFjZSxmY2MsbHAsbHByZWFkKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscCA9PSBOVUxMIHx8IGxwcmVhZCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogc2ltcGx5IGFzayBldmVyeSBzdHJlYW0gYW5kIHJldHVybiB0aGUgZmlyc3QgYmxvY2sgZm91bmQgKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+blN0cmVhbXM7IG4rKykgewogICAgSFJFU1VMVCBociA9IElBVklTdHJlYW1fUmVhZERhdGEoVGhpcy0+cFN0cmVhbXNbbl0ucFN0cmVhbSxmY2MsbHAsbHByZWFkKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgKmxwcmVhZCA9IDA7CiAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLDB4JTA4WCwlcCwlZClcbiIsaWZhY2UsZmNjLGxwLHNpemUpOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGxlbikKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsaWZhY2UsaW5mbyxsZW4pOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fU2V0SW5mbygoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSxpbmZvLGxlbik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopCnsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqVGhpcyA9IChJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5BZGRSZWYoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSkKewogIElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICpUaGlzID0gKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9BZGRSZWYoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblJlbGVhc2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSkKewogIElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICpUaGlzID0gKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlKTsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuR2V0RWRpdFN0cmVhbUltcGwoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxMUFZPSUQqcHBpbXBsKQp7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKlRoaXMgPSAoSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCkgLT4gJXBcbiIsIGlmYWNlLCBwcGltcGwsIFRoaXMtPnBhZSk7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CiAgYXNzZXJ0KHBwaW1wbCAhPSBOVUxMKTsKCiAgKnBwaW1wbCA9IFRoaXMtPnBhZTsKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==