LyoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIGludGVybmFsIGludGVyZmFjZSB0byBnZXQgYWNjZXNzIHRvIHRhYmxlIG9mIHN0cmVhbSBpbiBhbiBlZGl0YWJsZSBzdHJlYW0gKi8KCnR5cGVkZWYgc3RydWN0IF9FZGl0U3RyZWFtVGFibGUgewogIFBBVklTVFJFQU0gcFN0cmVhbTsgIC8qIHN0cmVhbSB3aGljaCBjb250YWlucyB0aGUgZGF0YSAqLwogIERXT1JEICAgICAgZHdTdGFydDsgIC8qIHdoZXJlIHN0YXJ0cyB0aGUgcGFydCB3aGljaCBpcyBhbHNvIG91ciAqLwogIERXT1JEICAgICAgZHdMZW5ndGg7IC8qIGhvdyBtYW55IGlzIGFsc28gaW4gdGhpcyBzdHJlYW0gKi8KfSBFZGl0U3RyZWFtVGFibGU7CgojZGVmaW5lIElOVEVSRkFDRSBJRWRpdFN0cmVhbUludGVybmFsCkRFQ0xBUkVfSU5URVJGQUNFXyhJRWRpdFN0cmVhbUludGVybmFsLElVbmtub3duKQp7CiAgICAvKioqIElVbmtub3duIG1ldGhvZHMgKioqLwogICAgU1RETUVUSE9EXyhIUkVTVUxULFF1ZXJ5SW50ZXJmYWNlKShUSElTXyBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwdk9iamVjdCkgUFVSRTsKICAgIFNURE1FVEhPRF8oVUxPTkcsQWRkUmVmKShUSElTKSBQVVJFOwogICAgU1RETUVUSE9EXyhVTE9ORyxSZWxlYXNlKShUSElTKSBQVVJFOwogICAgLyoqKiBJRWRpdFN0cmVhbUludGVybmFsIG1ldGhvZHMgKioqLwogICAgU1RETUVUSE9EKEdldEVkaXRTdHJlYW1JbXBsKShUSElTXyBMUFZPSUQqKSBQVVJFOwp9OwojdW5kZWYgSU5URVJGQUNFCgojZGVmaW5lIEVkaXRTdHJlYW1FbmQoVGhpcyxzdHJlYW1OcikgKChUaGlzKS0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgKyBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMpLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGgpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJRWRpdFN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQWRkUmVmKElBVklFZGl0U3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkN1dChJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5Db3B5KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSBwU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGxTdGFydCxMT05HIGxFbmQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DbG9uZShJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFWSVNUUkVBTSpwcFJlc3VsdCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblNldEluZm8oSUFWSUVkaXRTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBVklTVFJFQU1JTkZPVyBhc2ksTE9ORyBzaXplKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSUVkaXRTdHJlYW1WdGJsIGllZGl0c3RyZWFtID0gewogIElBVklFZGl0U3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUVkaXRTdHJlYW1fZm5BZGRSZWYsCiAgSUFWSUVkaXRTdHJlYW1fZm5SZWxlYXNlLAogIElBVklFZGl0U3RyZWFtX2ZuQ3V0LAogIElBVklFZGl0U3RyZWFtX2ZuQ29weSwKICBJQVZJRWRpdFN0cmVhbV9mblBhc3RlLAogIElBVklFZGl0U3RyZWFtX2ZuQ2xvbmUsCiAgSUFWSUVkaXRTdHJlYW1fZm5TZXRJbmZvCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLExPTkcqYnl0ZXNyZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcHdyaXR0ZW4sTE9ORypieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGllZGl0c3Rhc3QgPSB7CiAgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZiwKICBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5JbmZvLAogIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkLAogIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZihJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsTFBWT0lEKnBwaW1wbCk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElFZGl0U3RyZWFtSW50ZXJuYWxWdGJsIGllZGl0c3RyZWFtaW50ZXJuYWwgPSB7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblF1ZXJ5SW50ZXJmYWNlLAogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5BZGRSZWYsCiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblJlbGVhc2UsCiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSUVkaXRTdHJlYW1JbXBsIElBVklFZGl0U3RyZWFtSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JRWRpdEFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklFZGl0U3RyZWFtSW1wbCAqcGFlOwp9IElFZGl0QVZJU3RyZWFtSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JRWRpdFN0cmVhbUludGVybmFsSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJRWRpdFN0cmVhbUludGVybmFsVnRibCAqbHBWdGJsOwoKICAvKiBJRWRpdFN0cmVhbUludGVybmFsIHN0dWZmICovCiAgSUFWSUVkaXRTdHJlYW1JbXBsICpwYWU7Cn0gSUVkaXRTdHJlYW1JbnRlcm5hbEltcGw7CgpzdHJ1Y3QgX0lBVklFZGl0U3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJRWRpdFN0cmVhbVZ0YmwgKmxwVnRibDsKICBMT05HICByZWY7CgogIC8qIElBVklFZGl0U3RyZWFtIHN0dWZmICovCiAgSUVkaXRBVklTdHJlYW1JbXBsICAgICAgaUFWSVN0cmVhbTsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCBpRWRpdFN0cmVhbUludGVybmFsOwoKICBBVklTVFJFQU1JTkZPVyAgICAgICBzSW5mbzsKCiAgRWRpdFN0cmVhbVRhYmxlICAgICAqcFN0cmVhbXM7CiAgRFdPUkQgICAgICAgICAgICAgICAgblN0cmVhbXM7ICAgLyogY3VycmVudCBmaWxsIGxldmVsIG9mIHBTdHJlYW1zIHRhYmxlICovCiAgRFdPUkQgICAgICAgICAgICAgICAgblRhYmxlU2l6ZTsgLyogc2l6ZSBvZiBwU3RyZWFtcyB0YWJsZSAqLwoKICBCT09MICAgICAgICAgICAgICAgICBiRGVjb21wcmVzczsKICBQQVZJU1RSRUFNICAgICAgICAgICBwQ3VyU3RyZWFtOwogIFBHRVRGUkFNRSAgICAgICAgICAgIHBnOyAgICAgICAgIC8qIElHZXRGcmFtZSBmb3IgcEN1clN0cmVhbSAqLwogIExQQklUTUFQSU5GT0hFQURFUiAgIGxwRnJhbWU7ICAgIC8qIGZyYW1lIG9mIHBDdXJTdHJlYW0gKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KClBBVklFRElUU1RSRUFNIEFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKnBlZGl0ID0gTlVMTDsKCiAgcGVkaXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklFZGl0U3RyZWFtSW1wbCkpOwogIGlmIChwZWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIHBlZGl0LT5scFZ0YmwgICAgICAgICAgICA9ICZpZWRpdHN0cmVhbTsKICBwZWRpdC0+aUFWSVN0cmVhbS5scFZ0YmwgPSAmaWVkaXRzdGFzdDsKICBwZWRpdC0+aUFWSVN0cmVhbS5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5scFZ0YmwgPSAmaWVkaXRzdHJlYW1pbnRlcm5hbDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+cmVmID0gMTsKCiAgSUFWSVN0cmVhbV9DcmVhdGUoKFBBVklTVFJFQU0pJnBlZGl0LT5pQVZJU3RyZWFtLChMUEFSQU0pcHN0cmVhbSwwKTsKCiAgcmV0dXJuIChQQVZJRURJVFNUUkVBTSlwZWRpdDsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMsCgkJCQkJIERXT1JEIHBvcyxQQVZJU1RSRUFNICpwcFN0cmVhbSwKCQkJCQkgRFdPUkQqIHN0cmVhbVBvcywKCQkJCQkgRFdPUkQqIHN0cmVhbU5yLEJPT0wgYkZpbmRTYW1wbGUpCnsKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVsdSwlcCwlcCwlcCwlZClcbiIsVGhpcyxwb3MscHBTdHJlYW0sc3RyZWFtUG9zLAogICAgICAgIHN0cmVhbU5yLGJGaW5kU2FtcGxlKTsKCiAgaWYgKHBvcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBwb3MgLT0gVGhpcy0+c0luZm8uZHdTdGFydDsKICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+blN0cmVhbXM7IG4rKykgewogICAgaWYgKHBvcyA8IFRoaXMtPnBTdHJlYW1zW25dLmR3TGVuZ3RoKSB7CiAgICAgICpwcFN0cmVhbSAgPSBUaGlzLT5wU3RyZWFtc1tuXS5wU3RyZWFtOwogICAgICAqc3RyZWFtUG9zID0gVGhpcy0+cFN0cmVhbXNbbl0uZHdTdGFydCArIHBvczsKICAgICAgaWYgKHN0cmVhbU5yICE9IE5VTEwpCiAgICAgICAgKnN0cmVhbU5yID0gbjsKCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9CiAgICBwb3MgLT0gVGhpcy0+cFN0cmVhbXNbbl0uZHdMZW5ndGg7CiAgfQogIGlmIChwb3MgPT0gMCAmJiBiRmluZFNhbXBsZSkgewogICAgKnBwU3RyZWFtICA9IFRoaXMtPnBTdHJlYW1zWy0tbl0ucFN0cmVhbTsKICAgICpzdHJlYW1Qb3MgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIG4pOwogICAgaWYgKHN0cmVhbU5yICE9IE5VTEwpCiAgICAgICpzdHJlYW1OciA9IG47CgogICAgVFJBQ0UoIiAtLSBwb3M9MCAmJiBiPTEgLT4gKCVwLCVsdSwlbHUpXG4iLCpwcFN0cmVhbSwgKnN0cmVhbVBvcywgbik7CiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICAqcHBTdHJlYW0gPSBOVUxMOwogICAgKnN0cmVhbVBvcyA9IDA7CiAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgKnN0cmVhbU5yID0gMDsKCiAgICBUUkFDRSgiIC0+IEVSUk9SIChOVUxMLDAsMClcbiIpOwogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICB9Cn0KCnN0YXRpYyBMUFZPSUQgQVZJRklMRV9SZWFkRnJhbWUoSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MpCnsKICBQR0VURlJBTUUgcGc7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixUaGlzLHBzdHJlYW0scG9zKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICAvKiBpZiBzdHJlYW0gY2hhbmdlcyBtYWtlIHN1cmUgdGhhdCBvbmx5IHBhbGV0dGUgY2hhbmdlcyAqLwogIGlmIChUaGlzLT5wQ3VyU3RyZWFtICE9IHBzdHJlYW0pIHsKICAgIHBnID0gQVZJU3RyZWFtR2V0RnJhbWVPcGVuKHBzdHJlYW0sIE5VTEwpOwogICAgaWYgKHBnID09IE5VTEwpCiAgICAgIHJldHVybiBOVUxMOwogICAgaWYgKFRoaXMtPnBnICE9IE5VTEwpIHsKICAgICAgaWYgKElHZXRGcmFtZV9TZXRGb3JtYXQocGcsIFRoaXMtPmxwRnJhbWUsIE5VTEwsIDAsIDAsIC0xLCAtMSkpIHsKICAgICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKHBnKTsKICAgICAgICBFUlIoIjogSUdldEZyYW1lX1NldEZvcm1hdCBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgICB9CiAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoVGhpcy0+cGcpOwogICAgfQogICAgVGhpcy0+cGcgICAgICAgICA9IHBnOwogICAgVGhpcy0+cEN1clN0cmVhbSA9IHBzdHJlYW07CiAgfQoKICAvKiBub3cgZ2V0IHRoZSBkZWNvbXByZXNzZWQgZnJhbWUgKi8KICBUaGlzLT5scEZyYW1lID0gQVZJU3RyZWFtR2V0RnJhbWUoVGhpcy0+cGcsIHBvcyk7CiAgaWYgKFRoaXMtPmxwRnJhbWUgIT0gTlVMTCkKICAgIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmxwRnJhbWUtPmJpU2l6ZUltYWdlOwoKICByZXR1cm4gVGhpcy0+bHBGcmFtZTsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZW1vdmVTdHJlYW0oSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLCBEV09SRCBucikKewogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChuciA8IFRoaXMtPm5TdHJlYW1zKTsKCiAgLyogcmVtb3ZlIHBhcnQgbnIgKi8KICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbXNbbnJdLnBTdHJlYW0pOwogIFRoaXMtPm5TdHJlYW1zLS07CiAgaWYgKFRoaXMtPm5TdHJlYW1zIC0gbnIgPiAwKSB7CiAgICBtZW1tb3ZlKFRoaXMtPnBTdHJlYW1zICsgbnIsIFRoaXMtPnBTdHJlYW1zICsgbnIgKyAxLAogICAgICAgICAgICAoVGhpcy0+blN0cmVhbXMgLSBucikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgfQogIFRoaXMtPnBTdHJlYW1zW1RoaXMtPm5TdHJlYW1zXS5wU3RyZWFtICA9IE5VTEw7CiAgVGhpcy0+cFN0cmVhbXNbVGhpcy0+blN0cmVhbXNdLmR3U3RhcnQgID0gMDsKICBUaGlzLT5wU3RyZWFtc1tUaGlzLT5uU3RyZWFtc10uZHdMZW5ndGggPSAwOwoKICAvKiB0cnkgdG8gbWVyZ2UgdGhlIHBhcnQgYmVmb3JlIHRoZSBkZWxldGVkIG9uZSBhbmQgdGhlIG9uZSBhZnRlciBpdCAqLwogIGlmICgwIDwgbnIgJiYgMCA8IFRoaXMtPm5TdHJlYW1zICYmCiAgICAgIFRoaXMtPnBTdHJlYW1zW25yIC0gMV0ucFN0cmVhbSA9PSBUaGlzLT5wU3RyZWFtc1tucl0ucFN0cmVhbSkgewogICAgaWYgKEVkaXRTdHJlYW1FbmQoVGhpcywgbnIgLSAxKSA9PSBUaGlzLT5wU3RyZWFtc1tucl0uZHdTdGFydCkgewogICAgICBUaGlzLT5wU3RyZWFtc1tuciAtIDFdLmR3TGVuZ3RoICs9IFRoaXMtPnBTdHJlYW1zW25yXS5kd0xlbmd0aDsKICAgICAgcmV0dXJuIEFWSUZJTEVfUmVtb3ZlU3RyZWFtKFRoaXMsIG5yKTsKICAgIH0KICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBCT09MIEFWSUZJTEVfRm9ybWF0c0VxdWFsKFBBVklTVFJFQU0gYXZpMSwgUEFWSVNUUkVBTSBhdmkyKQp7CiAgTFBWT0lEIGZtdDEgPSBOVUxMLCBmbXQyID0gTlVMTDsKICBMT05HIHNpemUxLCBzaXplMiwgc3RhcnQxLCBzdGFydDI7CiAgQk9PTCBzdGF0dXMgPSBGQUxTRTsKCiAgYXNzZXJ0KGF2aTEgIT0gTlVMTCAmJiBhdmkyICE9IE5VTEwpOwoKICAvKiBnZXQgc3RyZWFtIHN0YXJ0cyBhbmQgY2hlY2sgZm9ybWF0IHNpemVzICovCiAgc3RhcnQxID0gQVZJU3RyZWFtU3RhcnQoYXZpMSk7CiAgc3RhcnQyID0gQVZJU3RyZWFtU3RhcnQoYXZpMik7CiAgaWYgKEZBSUxFRChBVklTdHJlYW1Gb3JtYXRTaXplKGF2aTEsIHN0YXJ0MSwgJnNpemUxKSkpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKEZBSUxFRChBVklTdHJlYW1Gb3JtYXRTaXplKGF2aTIsIHN0YXJ0MiwgJnNpemUyKSkpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKHNpemUxICE9IHNpemUyKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBzaXplcyBtYXRjaCwgbm93IGdldCBmb3JtYXRzIGFuZCBjb21wYXJlIHRoZW0gKi8KICBmbXQxID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUxKTsKICBpZiAoZm10MSA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwogIGlmIChTVUNDRUVERUQoQVZJU3RyZWFtUmVhZEZvcm1hdChhdmkxLCBzdGFydDEsIGZtdDEsICZzaXplMSkpKSB7CiAgICBmbXQyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUxKTsKICAgIGlmIChmbXQyICE9IE5VTEwpIHsKICAgICAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KGF2aTIsIHN0YXJ0MiwgZm10MiwgJnNpemUxKSkpCiAgICAgICAgc3RhdHVzID0gKG1lbWNtcChmbXQxLCBmbXQyLCBzaXplMSkgPT0gMCk7CiAgICB9CiAgfQoKICBpZiAoZm10MiAhPSBOVUxMKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm10Mik7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm10MSk7CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklFZGl0U3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSUVkaXRTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSBpZmFjZTsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUFWSVN0cmVhbTsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lFZGl0U3RyZWFtSW50ZXJuYWwsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUVkaXRTdHJlYW1JbnRlcm5hbDsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkFkZFJlZihJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBEV09SRCBpOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAoIXJlZikgewogICAgLyogcmVsZWFzZSBtZW1vcnkgKi8KICAgIGlmIChUaGlzLT5wZyAhPSBOVUxMKQogICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKFRoaXMtPnBnKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtcyAhPSBOVUxMKSB7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5uU3RyZWFtczsgaSsrKSB7CiAgICAgICAgaWYgKFRoaXMtPnBTdHJlYW1zW2ldLnBTdHJlYW0gIT0gTlVMTCkKICAgICAgICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtc1tpXS5wU3RyZWFtKTsKICAgICAgfQogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wU3RyZWFtcyk7CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ3V0KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSpwcFJlc3VsdCkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBQQVZJU1RSRUFNIHN0cmVhbTsKICBEV09SRCAgICAgIHN0YXJ0LCBsZW4sIHN0cmVhbVBvcywgc3RyZWFtTnI7CiAgSFJFU1VMVCAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsaWZhY2UscGxTdGFydCxwbExlbmd0aCxwcFJlc3VsdCk7CgogIGlmIChwcFJlc3VsdCAhPSBOVUxMKQogICAgKnBwUmVzdWx0ID0gTlVMTDsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8IHBsTGVuZ3RoID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogaWYgYXNrZWQgZm9yIGN1dHRlZCBwYXJ0IGNvcHkgaXQgYmVmb3JlIGRlbGV0aW5nICovCiAgaWYgKHBwUmVzdWx0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ29weShpZmFjZSwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICBzdGFydCA9ICpwbFN0YXJ0OwogIGxlbiAgID0gKnBsTGVuZ3RoOwoKICAvKiBub3cgZGVsZXRlIHRoZSByZXF1ZXN0ZWQgcGFydCAqLwogIHdoaWxlIChsZW4gPiAwKSB7CiAgICBociA9IEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgc3RhcnQsICZzdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0cmVhbVBvcywgJnN0cmVhbU5yLCBGQUxTRSk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ID09IHN0cmVhbVBvcykgewogICAgICAvKiBkZWxldGluZyBmcm9tIHN0YXJ0IG9mIHBhcnQgKi8KICAgICAgaWYgKGxlbiA8IFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCkgewogICAgICAgIHN0YXJ0ICs9IGxlbjsKICAgICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydCAgKz0gbGVuOwogICAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCAtPSBsZW47CiAgICAgICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gbGVuOwogICAgICAgIGxlbiA9IDA7CgogICAgICAgIC8qIHdlIG11c3QgcmV0dXJuIGRlY29tcHJlc3NlZCBkYXRhIG5vdyAqLwogICAgICAgIFRoaXMtPmJEZWNvbXByZXNzID0gVFJVRTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBkZWxldGluZyBob2xlIHBhcnQgKi8KICAgICAgICBsZW4gLT0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoOwogICAgICAgIEFWSUZJTEVfUmVtb3ZlU3RyZWFtKFRoaXMsc3RyZWFtTnIpOwogICAgICB9CiAgICB9IGVsc2UgaWYgKEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIDw9IHN0cmVhbVBvcyArIGxlbikgewogICAgICAvKiBkZWxldGluZyBhdCBlbmQgb2YgYSBwYXJ0ICovCiAgICAgIERXT1JEIGNvdW50ID0gRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgLSBzdHJlYW1Qb3M7CiAgICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC09IGNvdW50OwogICAgICBsZW4gICAgICAgICAgICAgICAgICAtPSBjb3VudDsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KICAgICAgICBzdHJlYW1Qb3MgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKICAgIH0gZWxzZSB7CiAgICAgIC8qIHNwbGl0dGluZyAqLwogICAgICBpZiAoVGhpcy0+blN0cmVhbXMgKyAxID49IFRoaXMtPm5UYWJsZVNpemUpIHsKICAgICAgICBUaGlzLT5wU3RyZWFtcyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPnBTdHJlYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPm5UYWJsZVNpemUgKyAzMikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICAgICAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgICBUaGlzLT5uVGFibGVTaXplICs9IDMyOwogICAgICB9CiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIDEsIFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsCiAgICAgICAgICAgICAgKFRoaXMtPm5TdHJlYW1zIC0gc3RyZWFtTnIpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgICBUaGlzLT5uU3RyZWFtcysrOwoKICAgICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5wU3RyZWFtKTsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5kd1N0YXJ0ICA9IHN0cmVhbVBvcyArIGxlbjsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5kd0xlbmd0aCA9CiAgICAgICAgRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLmR3U3RhcnQ7CgogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQogICAgICAgIHN0cmVhbVBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBsZW47CiAgICAgIGxlbiA9IDA7CiAgICB9CiAgfQoKICBUaGlzLT5zSW5mby5kd0VkaXRDb3VudCsrOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5Db3B5KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBwRWRpdDsKICBIUkVTVUxUIGhyOwogIExPTkcgc3RhcnQgPSAwOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogICpwcFJlc3VsdCA9IE5VTEw7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8ICpwbFN0YXJ0IDwgMCB8fCAqcGxMZW5ndGggPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY2hlY2sgYm91bmRzICovCiAgaWYgKCooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgKihMUERXT1JEKXBsTGVuZ3RoID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKCooTFBEV09SRClwbFN0YXJ0IDwgVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgKihMUERXT1JEKXBsTGVuZ3RoIC09IFRoaXMtPnNJbmZvLmR3U3RhcnQgLSAqKExQRFdPUkQpcGxTdGFydDsKICAgICooTFBEV09SRClwbFN0YXJ0ICAgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgaWYgKCpwbExlbmd0aCA8IDApCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgfQogIGlmICgqKExQRFdPUkQpcGxTdGFydCArICooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgICooTFBEV09SRClwbExlbmd0aCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCAtCiAgICAgICooTFBEV09SRClwbFN0YXJ0OwoKICBwRWRpdCA9IChJQVZJRWRpdFN0cmVhbUltcGwqKUFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShOVUxMKTsKICBpZiAocEVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IElBVklFZGl0U3RyZWFtX1Bhc3RlKChQQVZJRURJVFNUUkVBTSlwRWRpdCwmc3RhcnQscGxMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICpwbFN0YXJ0ICsgKnBsTGVuZ3RoKTsKICAqcGxTdGFydCA9IHN0YXJ0OwogIGlmIChGQUlMRUQoaHIpKQogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZSgoUEFWSUVESVRTVFJFQU0pcEVkaXQpOwogIGVsc2UKICAgICpwcFJlc3VsdCA9IChQQVZJU1RSRUFNKSZwRWRpdC0+aUFWSVN0cmVhbTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSBwU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGxTdGFydCxMT05HIGxMZW5ndGgpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgQVZJU1RSRUFNSU5GT1cgICAgICBzcmNJbmZvOwogIElFZGl0U3RyZWFtSW50ZXJuYWwqcEludGVybmFsID0gTlVMTDsKICBJQVZJRWRpdFN0cmVhbUltcGwgKnBFZGl0ID0gTlVMTDsKICBQQVZJU1RSRUFNICAgICAgICAgIHBTdHJlYW07CiAgRFdPUkQgICAgICAgICAgICAgICBzdGFydFBvcywgZW5kUG9zLCBzdHJlYW1OciwgblN0cmVhbXM7CiAgVUxPTkcgICAgICAgICAgICAgICBuOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVsZCwlbGQpXG4iLGlmYWNlLHBsU3RhcnQscGxMZW5ndGgsCglwU291cmNlLGxTdGFydCxsTGVuZ3RoKTsKCiAgaWYgKHBTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKnBsU3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOyAvKiBDYW4ndCBwYXN0ZSB3aXRoIGhvbGVzICovCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocFNvdXJjZSwgJnNyY0luZm8sIHNpemVvZihzcmNJbmZvKSkpKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICBpZiAobFN0YXJ0IDwgc3JjSW5mby5kd1N0YXJ0IHx8IGxTdGFydCA+PSBzcmNJbmZvLmR3U3RhcnQgKyBzcmNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSAwKSB7CiAgICAvKiBUaGlzIHN0cmVhbSBpcyBlbXB0eSAqLwogICAgSUFWSVN0cmVhbV9JbmZvKHBTb3VyY2UsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ICA9ICpwbFN0YXJ0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSAwOwogIH0KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzcmNJbmZvLmZjY1R5cGUpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBkaWZmZXJlbnQgc3RyZWFtIHR5cGVzICovCiAgaWYgKGxMZW5ndGggPT0gLTEpIC8qIENvcHkgdGhlIGhvbGUgc3RyZWFtICovCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd0xlbmd0aDsKICBpZiAobFN0YXJ0ICsgbExlbmd0aCA+IHNyY0luZm8uZHdTdGFydCArIHNyY0luZm8uZHdMZW5ndGgpCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd1N0YXJ0ICsgc3JjSW5mby5kd0xlbmd0aCAtIGxTdGFydDsKICBpZiAobExlbmd0aCArICpwbFN0YXJ0ID49IDB4ODAwMDAwMDApCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogc3RyZWFtdHlwZSBzcGVjaWZpYyB0ZXN0cyAqLwogIGlmIChzcmNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICBMT05HIHNpemU7CgogICAgc2l6ZSA9IHNyY0luZm8ucmNGcmFtZS5yaWdodCAtIHNyY0luZm8ucmNGcmFtZS5sZWZ0OwogICAgaWYgKHNpemUgIT0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogRklYTUU6IENhbid0IEdldEZyYW1lIGNvbnZlcnQgaXQ/ICovCiAgICBzaXplID0gc3JjSW5mby5yY0ZyYW1lLmJvdHRvbSAtIHNyY0luZm8ucmNGcmFtZS50b3A7CiAgICBpZiAoc2l6ZSAhPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBGSVhNRTogQ2FuJ3QgR2V0RnJhbWUgY29udmVydCBpdD8gKi8KICB9IGVsc2UgaWYgKHNyY0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKICAgIGlmICghIEFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UgewogICAgLyogRklYTUU6IHN0cmVhbXR5cGVNSURJIGFuZCBzdHJlYW10eXBlVEVYVCAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIHRyeSB0byBnZXQgYW4gSUVkaXRTdHJlYW1JbnRlcm5hbCBpbnRlcmZhY2UgKi8KICBpZiAoU1VDQ0VFREVEKElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFNvdXJjZSwgJklJRF9JRWRpdFN0cmVhbUludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKikmcEludGVybmFsKSkpIHsKICAgIHBJbnRlcm5hbC0+bHBWdGJsLT5HZXRFZGl0U3RyZWFtSW1wbChwSW50ZXJuYWwsIChMUFZPSUQqKSZwRWRpdCk7CiAgICBwSW50ZXJuYWwtPmxwVnRibC0+UmVsZWFzZShwSW50ZXJuYWwpOwogIH0KCiAgLyogZm9yIHZpZGVvIG11c3QgY2hlY2sgZm9yIGNoYW5nZSBvZiBmb3JtYXQgKi8KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAgIC8qIE5lZWQgdG8gZGVjb21wcmVzcyBpZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG1hdGNoZXM6CiAgICAgICAqICAtIHBTb3VyY2UgaXMgYW4gZWRpdGFibGUgc3RyZWFtIHdoaWNoIGRlY29tcHJlc3NlcwogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiBwU291cmNlIGlzbid0IGxTdGFydAogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiB0aGlzIHN0cmVhbSBpc24ndCAqcGxTdGFydAogICAgICAgKiAgLSB0aGUgZm9ybWF0IG9mIHBTb3VyY2UgZG9lc24ndCBtYXRjaCB0aGlzIG9uZQogICAgICAgKi8KICAgICAgaWYgKChwRWRpdCAhPSBOVUxMICYmIHBFZGl0LT5iRGVjb21wcmVzcykgfHwKCSAgQVZJU3RyZWFtTmVhcmVzdEtleUZyYW1lKHBTb3VyY2UsIGxTdGFydCkgIT0gbFN0YXJ0IHx8CgkgIEFWSVN0cmVhbU5lYXJlc3RLZXlGcmFtZSgoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwgKnBsU3RhcnQpICE9ICpwbFN0YXJ0IHx8CgkgIChUaGlzLT5uU3RyZWFtcyA+IDAgJiYgIUFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkpIHsKCS8qIFVzZSBmaXJzdCBzdHJlYW0gcGFydCB0byBnZXQgZm9ybWF0IHRvIGNvbnZlcnQgZXZlcnl0aGluZyB0byAqLwoJQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgVGhpcy0+cFN0cmVhbXNbMF0ucFN0cmVhbSwKCQkJICBUaGlzLT5wU3RyZWFtc1swXS5kd1N0YXJ0KTsKCgkvKiBDaGVjayBpZiB3ZSBjb3VsZCBjb252ZXJ0IHRoZSBzb3VyY2Ugc3RyZWFtcyB0byB0aGUgZGlzaXJlZCBmb3JtYXQuLi4gKi8KCWlmIChwRWRpdCAhPSBOVUxMKSB7CgkgIGlmIChGQUlMRUQoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJCQkgICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIFRSVUUpKSkKCSAgICByZXR1cm4gQVZJRVJSX0lOVEVSTkFMOwoJICBmb3IgKG4gPSBsU3RhcnQ7IG4gPCBsU3RhcnQgKyBsTGVuZ3RoOyBzdHJlYW1OcisrKSB7CgkgICAgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0ucFN0cmVhbSwgc3RhcnRQb3MpID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCSAgICBzdGFydFBvcyA9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKCSAgICBuICs9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CgkgIH0KCX0gZWxzZSBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcFNvdXJjZSwgbFN0YXJ0KSA9PSBOVUxMKQoJICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCglUaGlzLT5iRGVjb21wcmVzcyAgICAgID0gVFJVRTsKCVRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgPSAwOwogICAgICB9CiAgICB9IGVsc2UgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBTb3VyY2UsIGxTdGFydCkgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7IC8qIENhbid0IGNvbnZlcnQgc291cmNlIHRvIG93biBmb3JtYXQgKi8KICB9IC8qIEZJWE1FOiBzb21ldGhpbmcgc3BlY2lhbCBmb3IgdGhlIG90aGVyIGZvcm1hdHM/ICovCgogIC8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGVub3VnaCBtZW1vcnkgZm9yIHBhcnRzICovCiAgaWYgKHBFZGl0ICE9IE5VTEwpIHsKICAgIERXT1JEIG5MYXN0U3RyZWFtOwoKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCArIGxMZW5ndGgsICZwU3RyZWFtLAoJCQkgICAgICAmZW5kUG9zLCAmbkxhc3RTdHJlYW0sIFRSVUUpOwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChuTGFzdFN0cmVhbSA9PSBzdHJlYW1OcikKICAgICAgbkxhc3RTdHJlYW0rKzsKCiAgICBuU3RyZWFtcyA9IG5MYXN0U3RyZWFtIC0gc3RyZWFtTnI7CiAgfSBlbHNlIAogICAgblN0cmVhbXMgPSAxOwogIGlmIChUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMSA+IFRoaXMtPm5UYWJsZVNpemUpIHsKICAgIG4gPSBUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMzM7CgogICAgVGhpcy0+cFN0cmVhbXMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5wU3RyZWFtcywgbiAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPm5UYWJsZVNpemUgPSBuOwogIH0KCiAgaWYgKHBsTGVuZ3RoICE9IE5VTEwpCiAgICAqcGxMZW5ndGggPSBsTGVuZ3RoOwoKICAvKiBub3cgZG8gdGhlIHJlYWwgd29yayAqLwogIGlmIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPiAqcGxTdGFydCkgewogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCAqcGxTdGFydCwgJnBTdHJlYW0sCgkJCSAgICAgICZzdGFydFBvcywgJnN0cmVhbU5yLCBGQUxTRSk7CiAgICBpZiAoc3RhcnRQb3MgIT0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQpIHsKICAgICAgLyogc3BsaXQgc3RyZWFtIHN0cmVhbU5yIGF0IHN0YXJ0UG9zICovCiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIG5TdHJlYW1zICsgMSwKCSAgICAgIFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsCgkgICAgICAoVGhpcy0+blN0cmVhbXMgKyBuU3RyZWFtcyAtIHN0cmVhbU5yICsgMSkgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CgogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDJdLmR3TGVuZ3RoID0KCUVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIgKyAyKSAtIHN0YXJ0UG9zOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDJdLmR3U3RhcnQgPSBzdGFydFBvczsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KCXN0YXJ0UG9zIC0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQ7CiAgICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5wU3RyZWFtKTsKICAgICAgc3RyZWFtTnIrKzsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGluc2VydCBiZWZvcmUgc3RyZWFtIGF0IHN0cmVhbU5yICovCiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIG5TdHJlYW1zLCBUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yLAoJICAgICAgKFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgLSBzdHJlYW1OcikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICB9CiAgfSBlbHNlIC8qIGFwcGVuZCB0aGUgc3RyZWFtcyAqLwogICAgc3RyZWFtTnIgPSBUaGlzLT5uU3RyZWFtczsKCiAgaWYgKHBFZGl0ICE9IE5VTEwpIHsKICAgIC8qIGluc2VydCB0aGUgcGFydHMgb2YgdGhlIGVkaXRhYmxlIHN0cmVhbSBpbnN0ZWFkIG9mIGl0c2VsZiAqLwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0ICsgbExlbmd0aCwgJnBTdHJlYW0sCgkJCSAgICAgICZlbmRQb3MsIE5VTEwsIEZBTFNFKTsKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCwgJnBTdHJlYW0sICZzdGFydFBvcywgJm4sIEZBTFNFKTsKCiAgICBtZW1jcHkoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciwgcEVkaXQtPnBTdHJlYW1zICsgbiwKCSAgIG5TdHJlYW1zICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0IDwgc3RhcnRQb3MpIHsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KCUVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIC0gc3RhcnRQb3M7CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICA9IHN0YXJ0UG9zOwogICAgfQogICAgaWYgKGVuZFBvcyA8IEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIgKyBuU3RyZWFtcykpCiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgblN0cmVhbXNdLmR3TGVuZ3RoID0KCWVuZFBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgblN0cmVhbXNdLmR3U3RhcnQ7CiAgfSBlbHNlIHsKICAgIC8qIGEgc2ltcGxlIHN0cmVhbSAqLwogICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLnBTdHJlYW0gID0gcFNvdXJjZTsKICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICA9IGxTdGFydDsKICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCA9IGxMZW5ndGg7CiAgfQoKICBmb3IgKG4gPSAwOyBuIDwgblN0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyBuXS5wU3RyZWFtKTsKICAgIGlmICgwIDwgc3RyZWFtTnIgKyBuICYmCglUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIG4gLSAxXS5wU3RyZWFtICE9IFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgbl0ucFN0cmVhbSkgewogICAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKICAgICAgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCsrOwogICAgfQogIH0KICBUaGlzLT5zSW5mby5kd0VkaXRDb3VudCsrOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICs9IGxMZW5ndGg7CiAgVGhpcy0+blN0cmVhbXMgKz0gblN0cmVhbXM7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkNsb25lKElBVklFZGl0U3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIElBVklFZGl0U3RyZWFtSW1wbCogcEVkaXQ7CiAgRFdPUkQgaTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsaWZhY2UscHBSZXN1bHQpOwoKICBpZiAocHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgKnBwUmVzdWx0ID0gTlVMTDsKCiAgcEVkaXQgPSAoSUFWSUVkaXRTdHJlYW1JbXBsKilBVklGSUxFX0NyZWF0ZUVkaXRTdHJlYW0oTlVMTCk7CiAgaWYgKHBFZGl0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBpZiAoVGhpcy0+blN0cmVhbXMgPiBwRWRpdC0+blRhYmxlU2l6ZSkgewogICAgcEVkaXQtPnBTdHJlYW1zID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgcEVkaXQtPnBTdHJlYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+blN0cmVhbXMgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICBpZiAocEVkaXQtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgcEVkaXQtPm5UYWJsZVNpemUgPSBUaGlzLT5uU3RyZWFtczsKICB9CiAgcEVkaXQtPm5TdHJlYW1zID0gVGhpcy0+blN0cmVhbXM7CiAgbWVtY3B5KHBFZGl0LT5wU3RyZWFtcywgVGhpcy0+cFN0cmVhbXMsCiAgICAgICAgIFRoaXMtPm5TdHJlYW1zICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogIG1lbWNweSgmcEVkaXQtPnNJbmZvLCZUaGlzLT5zSW5mbyxzaXplb2YoVGhpcy0+c0luZm8pKTsKICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+blN0cmVhbXM7IGkrKykgewogICAgaWYgKHBFZGl0LT5wU3RyZWFtc1tpXS5wU3RyZWFtICE9IE5VTEwpCiAgICAgIElBVklTdHJlYW1fQWRkUmVmKHBFZGl0LT5wU3RyZWFtc1tpXS5wU3RyZWFtKTsKICB9CgogICpwcFJlc3VsdCA9IChQQVZJU1RSRUFNKSZwRWRpdC0+aUFWSVN0cmVhbTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuU2V0SW5mbyhJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSxMT05HIHNpemUpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhc2ksc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplICE9IHNpemVvZihBVklTVFJFQU1JTkZPVykpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CiAgaWYgKGFzaS0+ZHdTY2FsZSA9PSAwIHx8IGFzaS0+ZHdSYXRlID09IDAgfHwgKExPTkcpYXNpLT5kd1F1YWxpdHkgPCAtMSB8fAogICAgICBhc2ktPmR3UXVhbGl0eSA+IElDUVVBTElUWV9ISUdIKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgVGhpcy0+c0luZm8ud0xhbmd1YWdlID0gYXNpLT53TGFuZ3VhZ2U7CiAgVGhpcy0+c0luZm8ud1ByaW9yaXR5ID0gYXNpLT53UHJpb3JpdHk7CiAgVGhpcy0+c0luZm8uZHdTdGFydCAgID0gYXNpLT5kd1N0YXJ0OwogIGlmIChhc2ktPmR3UmF0ZSAhPSAwKQogICAgVGhpcy0+c0luZm8uZHdSYXRlICA9IGFzaS0+ZHdSYXRlOwogIGlmIChhc2ktPmR3U2NhbGUgIT0gMCkKICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUgPSBhc2ktPmR3U2NhbGU7CiAgaWYgKGFzaS0+ZHdRdWFsaXR5IDw9IElDUVVBTElUWV9ISUdIKQogICAgVGhpcy0+c0luZm8uZHdRdWFsaXR5ID0gSUNRVUFMSVRZX0hJR0g7CiAgQ29weVJlY3QoJlRoaXMtPnNJbmZvLnJjRnJhbWUsICZhc2ktPnJjRnJhbWUpOwogIG1lbWNweSgmVGhpcy0+c0luZm8uc3pOYW1lLCAmYXNpLT5zek5hbWUsIHNpemVvZihhc2ktPnN6TmFtZSkpOwogIFRoaXMtPnNJbmZvLmR3RWRpdENvdW50Kys7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaikKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlLHJlZmlpZCxvYmopOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSkKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX0FkZFJlZigoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSk7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSppZmFjZSkKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1JlbGVhc2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFlOwoKICBpZiAobFBhcmFtMiAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpIHsKICAgIFRoaXMtPnBTdHJlYW1zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIDI1NiAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPm5UYWJsZVNpemUgPSAyNTY7CiAgfQoKICBpZiAobFBhcmFtMSAhPSAwKSB7CiAgICBJQVZJU3RyZWFtX0luZm8oKFBBVklTVFJFQU0pbFBhcmFtMSwgJlRoaXMtPnNJbmZvLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKICAgIElBVklTdHJlYW1fQWRkUmVmKChQQVZJU1RSRUFNKWxQYXJhbTEpOwogICAgVGhpcy0+cFN0cmVhbXNbMF0ucFN0cmVhbSAgPSAoUEFWSVNUUkVBTSlsUGFyYW0xOwogICAgVGhpcy0+cFN0cmVhbXNbMF0uZHdTdGFydCAgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgVGhpcy0+cFN0cmVhbXNbMF0uZHdMZW5ndGggPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICAgIFRoaXMtPm5TdHJlYW1zID0gMTsKICB9CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsaWZhY2UscHNpLHNpemUpOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgaWYgKFRoaXMtPnBhZS0+YkRlY29tcHJlc3MpCiAgICBUaGlzLT5wYWUtPnNJbmZvLmZjY0hhbmRsZXIgPSAwOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+cGFlLT5zSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+cGFlLT5zSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPnBhZS0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBmbGFncykKewogIElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcyA9ICgoSUVkaXRBVklTdHJlYW1JbXBsKiBjb25zdClpZmFjZSktPnBhZTsKICBQQVZJU1RSRUFNIHN0cmVhbTsKICBEV09SRCAgICAgIHN0cmVhbVBvcywgc3RyZWFtTnI7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkKICAgIHBvcyA9IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQ7CgogIC8qIG91dHNpZGUgb2Ygc3RyZWFtPyAqLwogIGlmIChwb3MgPCAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0IHx8CiAgICAgIChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgKyAoTE9ORylUaGlzLT5zSW5mby5kd0xlbmd0aCA8PSBwb3MpCiAgICByZXR1cm4gLTE7CgogIC8qIG1hcCBvdXIgcG9zaXRpb24gdG8gYSBzdHJlYW0gYW5kIHBvc2l0aW9uIGluIGl0ICovCiAgaWYgKEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgcG9zLCAmc3RyZWFtLCAmc3RyZWFtUG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdHJlYW1OciwgVFJVRSkpCiAgICByZXR1cm4gLTE7IC8qIGRvZXNuJ3QgZXhpc3QgKi8KCiAgaWYgKFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAvKiBvbmx5IG9uZSBzdHJlYW0gLS0gZm9ybWF0IGNoYW5nZXMgb25seSBhdCBzdGFydCAqLwogICAgaWYgKGZsYWdzICYgRklORF9GT1JNQVQpCiAgICAgIHJldHVybiAoZmxhZ3MgJiBGSU5EX05FWFQgPyAtMSA6IDApOwoKICAgIC8qIEZJWE1FOiBtYXAgcG9zaXRpb25zIGJhY2sgdG8gdXMgKi8KICAgIHJldHVybiBJQVZJU3RyZWFtX0ZpbmRTYW1wbGUoc3RyZWFtLCBzdHJlYW1Qb3MsIGZsYWdzKTsKICB9IGVsc2UgewogICAgLyogYXNzdW1lIGNoYW5nZSBvZiBmb3JtYXQgZXZlcnkgZnJhbWUgKi8KICAgIHJldHVybiBwb3M7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGZvcm1hdCxMT05HKmZtdHNpemUpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgTFBCSVRNQVBJTkZPSEVBREVSICBscDsKICBQQVZJU1RSRUFNICAgICAgICAgIHN0cmVhbTsKICBEV09SRCAgICAgICAgICAgICAgIG47CiAgSFJFU1VMVCAgICAgICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLGlmYWNlLHBvcyxmb3JtYXQsZm10c2l6ZSk7CgogIGlmIChmbXRzaXplID09IE5VTEwgfHwgcG9zIDwgVGhpcy0+c0luZm8uZHdTdGFydCB8fAogICAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPD0gcG9zKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogZmluZCBzdHJlYW0gY29ycmVzcG9uZGluZyB0byBwb3NpdGlvbiAqLwogIGhyID0gQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBwb3MsICZzdHJlYW0sICZuLCBOVUxMLCBGQUxTRSk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKQogICAgcmV0dXJuIElBVklTdHJlYW1fUmVhZEZvcm1hdChzdHJlYW0sIG4sIGZvcm1hdCwgZm10c2l6ZSk7CgogIGxwID0gKExQQklUTUFQSU5GT0hFQURFUilBVklGSUxFX1JlYWRGcmFtZShUaGlzLCBzdHJlYW0sIG4pOwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICBpZiAobHAtPmJpQml0Q291bnQgPD0gOCkgewogICAgbiAgPSAobHAtPmJpQ2xyVXNlZCA+IDAgPyBscC0+YmlDbHJVc2VkIDogMSA8PCBscC0+YmlCaXRDb3VudCk7CiAgICBuICo9IHNpemVvZihSR0JRVUFEKTsKICB9IGVsc2UKICAgIG4gPSAwOwogIG4gKz0gbHAtPmJpU2l6ZTsKICAKICBtZW1jcHkoZm9ybWF0LCBscCwgbWluKChMT05HKW4sICpmbXRzaXplKSk7CiAgaHIgPSAoKExPTkcpbiA+ICpmbXRzaXplID8gQVZJRVJSX0JVRkZFUlRPT1NNQUxMIDogQVZJRVJSX09LKTsKICAqZm10c2l6ZSA9IG47CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSkKewogIFRSQUNFKCIoJXAsJWxkLCVwLCVsZClcbiIsaWZhY2UscG9zLGZvcm1hdCxmb3JtYXRzaXplKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLExPTkcqYnl0ZXNyZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcGxlc3JlYWQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgUEFWSVNUUkVBTSBzdHJlYW07CiAgRFdPUkQgICBzdHJlYW1Qb3MsIHN0cmVhbU5yOwogIExPTkcgICAgcmVhZEJ5dGVzLCByZWFkU2FtcGxlcywgY291bnQ7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwlcCwlcCkgLS0gMHglMDhsWFxuIixpZmFjZSxzdGFydCxzYW1wbGVzLAogICAgICAgIGJ1ZmZlcixidWZmZXJzaXplLGJ5dGVzcmVhZCxzYW1wbGVzcmVhZCxUaGlzLT5zSW5mby5mY2NUeXBlKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKICBpZiAoYnVmZmVyc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CiAgaWYgKChEV09SRClzdGFydCA8IFRoaXMtPnNJbmZvLmR3U3RhcnQgfHwKICAgICAgVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKERXT1JEKXN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKCEgVGhpcy0+YkRlY29tcHJlc3MpIHsKICAgIC8qIGF1ZGlvIGxpa2UgZGF0YSAtLSBzYW1wbGUtYmFzZWQgKi8KICAgIGRvIHsKICAgICAgaWYgKHNhbXBsZXMgPT0gMCkKICAgICAgICByZXR1cm4gQVZJRVJSX09LOyAvKiBub3RoaW5nIGF0IGFsbCBvciBhbHJlYWR5IGRvbmUgKi8KCiAgICAgIGlmIChGQUlMRUQoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBzdGFydCwgJnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdHJlYW1Qb3MsICZzdHJlYW1OciwgRkFMU0UpKSkKICAgICAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICAgICAgLyogbGltaXQgdG8gZW5kIG9mIHRoZSBzdHJlYW0gKi8KICAgICAgY291bnQgPSBzYW1wbGVzOwogICAgICBpZiAoc3RyZWFtUG9zICsgY291bnQgPiBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSkKICAgICAgICBjb3VudCA9IEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIC0gc3RyZWFtUG9zOwoKICAgICAgaHIgPSBJQVZJU3RyZWFtX1JlYWQoc3RyZWFtLCBzdHJlYW1Qb3MsIGNvdW50LCBidWZmZXIsIGJ1ZmZlcnNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZWFkQnl0ZXMsICZyZWFkU2FtcGxlcyk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgIHJldHVybiBocjsKICAgICAgaWYgKHJlYWRCeXRlcyA9PSAwICYmIHJlYWRTYW1wbGVzID09IDAgJiYgY291bnQgIT0gMCkKICAgICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOyAvKiBmb3IgYmFkIHN0cmVhbSBpbXBsZW1lbnRhdGlvbnMgKi8KCiAgICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAgICpzYW1wbGVzcmVhZCArPSByZWFkU2FtcGxlczsKICAgICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAgICpieXRlc3JlYWQgKz0gcmVhZEJ5dGVzOwogICAgICBpZiAoYnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBidWZmZXIgPSAoKExQQllURSlidWZmZXIpK3JlYWRCeXRlczsKICAgICAgICBidWZmZXJzaXplICAgICAtPSByZWFkQnl0ZXM7CiAgICAgIH0KICAgICAgc3RhcnQgICArPSBjb3VudDsKICAgICAgc2FtcGxlcyAtPSBjb3VudDsKICAgIH0gd2hpbGUgKFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA+IHN0YXJ0KTsKICB9IGVsc2UgewogICAgLyogdmlkZW8gbGlrZSBkYXRhIC0tIGZyYW1lLWJhc2VkICovCiAgICBMUEJJVE1BUElORk9IRUFERVIgbHA7CgogICAgaWYgKHNhbXBsZXMgPT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgICBpZiAoRkFJTEVEKEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgc3RhcnQsICZzdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0cmVhbVBvcywgJnN0cmVhbU5yLCBGQUxTRSkpKQogICAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICAgIGxwID0gQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgc3RyZWFtLCBzdHJlYW1Qb3MpOwogICAgaWYgKGxwID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfRVJST1I7CgogICAgaWYgKGJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgIC8qIG5lZWQgc2l6ZSBvZiBmb3JtYXQgdG8gc2tpcCAqLwogICAgICBpZiAobHAtPmJpQml0Q291bnQgPD0gOCkgewogICAgICAgIGNvdW50ICA9IGxwLT5iaUNsclVzZWQgPiAwID8gbHAtPmJpQ2xyVXNlZCA6IDEgPDwgbHAtPmJpQml0Q291bnQ7CiAgICAgICAgY291bnQgKj0gc2l6ZW9mKFJHQlFVQUQpOwogICAgICB9IGVsc2UKICAgICAgICBjb3VudCA9IDA7CiAgICAgIGNvdW50ICs9IGxwLT5iaVNpemU7CgogICAgICBpZiAoYnVmZmVyc2l6ZSA8IGxwLT5iaVNpemVJbWFnZSkKICAgICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogICAgICBtZW1jcHkoYnVmZmVyLCAoTFBCWVRFKWxwICsgY291bnQsIGxwLT5iaVNpemVJbWFnZSk7CiAgICB9CgogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gbHAtPmJpU2l6ZUltYWdlOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IDE7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcHdyaXR0ZW4sTE9ORypieXRlc3dyaXR0ZW4pCnsKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JTA4bFgsJXAsJXApXG4iLGlmYWNlLHN0YXJ0LHNhbXBsZXMsYnVmZmVyLAogICAgICAgIGJ1ZmZlcnNpemUsZmxhZ3Msc2FtcHdyaXR0ZW4sYnl0ZXN3cml0dGVuKTsKCiAgLyogYmUgc3VyZSByZXR1cm4gcGFyYW1ldGVycyBoYXZlIGNvcnJlY3QgdmFsdWVzICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLGlmYWNlLHN0YXJ0LHNhbXBsZXMpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fQ3V0KChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlLCZzdGFydCwmc2FtcGxlcyxOVUxMKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HICpscHJlYWQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgRFdPUkQgbjsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIixpZmFjZSxmY2MsbHAsbHByZWFkKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscCA9PSBOVUxMIHx8IGxwcmVhZCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogc2ltcGx5IGFzayBldmVyeSBzdHJlYW0gYW5kIHJldHVybiB0aGUgZmlyc3QgYmxvY2sgZm91bmQgKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+blN0cmVhbXM7IG4rKykgewogICAgSFJFU1VMVCBociA9IElBVklTdHJlYW1fUmVhZERhdGEoVGhpcy0+cFN0cmVhbXNbbl0ucFN0cmVhbSxmY2MsbHAsbHByZWFkKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgKmxwcmVhZCA9IDA7CiAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJWxkKVxuIixpZmFjZSxmY2MsbHAsc2l6ZSk7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgbGVuKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsaWZhY2UsaW5mbyxsZW4pOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fU2V0SW5mbygoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSxpbmZvLGxlbik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopCnsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqVGhpcyA9IChJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5BZGRSZWYoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSkKewogIElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICpUaGlzID0gKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9BZGRSZWYoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblJlbGVhc2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSkKewogIElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICpUaGlzID0gKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlKTsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuR2V0RWRpdFN0cmVhbUltcGwoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxMUFZPSUQqcHBpbXBsKQp7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKlRoaXMgPSAoSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCkgLT4gJXBcbiIsIGlmYWNlLCBwcGltcGwsIFRoaXMtPnBhZSk7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CiAgYXNzZXJ0KHBwaW1wbCAhPSBOVUxMKTsKCiAgKnBwaW1wbCA9IFRoaXMtPnBhZTsKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==