LyoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIGludGVybmFsIGludGVyZmFjZSB0byBnZXQgYWNjZXNzIHRvIHRhYmxlIG9mIHN0cmVhbSBpbiBhbiBlZGl0YWJsZSBzdHJlYW0gKi8KCnR5cGVkZWYgc3RydWN0IF9FZGl0U3RyZWFtVGFibGUgewogIFBBVklTVFJFQU0gcFN0cmVhbTsgIC8qIHN0cmVhbSB3aGljaCBjb250YWlucyB0aGUgZGF0YSAqLwogIERXT1JEICAgICAgZHdTdGFydDsgIC8qIHdoZXJlIHN0YXJ0cyB0aGUgcGFydCB3aGljaCBpcyBhbHNvIG91ciAqLwogIERXT1JEICAgICAgZHdMZW5ndGg7IC8qIGhvdyBtYW55IGlzIGFsc28gaW4gdGhpcyBzdHJlYW0gKi8KfSBFZGl0U3RyZWFtVGFibGU7CgojZGVmaW5lIElOVEVSRkFDRSBJRWRpdFN0cmVhbUludGVybmFsCkRFQ0xBUkVfSU5URVJGQUNFXyhJRWRpdFN0cmVhbUludGVybmFsLElVbmtub3duKQp7CiAgICAvKioqIElVbmtub3duIG1ldGhvZHMgKioqLwogICAgU1RETUVUSE9EXyhIUkVTVUxULFF1ZXJ5SW50ZXJmYWNlKShUSElTXyBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwdk9iamVjdCkgUFVSRTsKICAgIFNURE1FVEhPRF8oVUxPTkcsQWRkUmVmKShUSElTKSBQVVJFOwogICAgU1RETUVUSE9EXyhVTE9ORyxSZWxlYXNlKShUSElTKSBQVVJFOwogICAgLyoqKiBJRWRpdFN0cmVhbUludGVybmFsIG1ldGhvZHMgKioqLwogICAgU1RETUVUSE9EKEdldEVkaXRTdHJlYW1JbXBsKShUSElTXyBMUFZPSUQqKSBQVVJFOwp9OwojdW5kZWYgSU5URVJGQUNFCgojZGVmaW5lIEVkaXRTdHJlYW1FbmQoVGhpcyxzdHJlYW1OcikgKChUaGlzKS0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgKyBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMpLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGgpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJRWRpdFN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQWRkUmVmKElBVklFZGl0U3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkN1dChJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5Db3B5KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSBwU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGxTdGFydCxMT05HIGxFbmQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DbG9uZShJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFWSVNUUkVBTSpwcFJlc3VsdCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblNldEluZm8oSUFWSUVkaXRTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBVklTVFJFQU1JTkZPVyBhc2ksTE9ORyBzaXplKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSUVkaXRTdHJlYW1WdGJsIGllZGl0c3RyZWFtID0gewogIElBVklFZGl0U3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUVkaXRTdHJlYW1fZm5BZGRSZWYsCiAgSUFWSUVkaXRTdHJlYW1fZm5SZWxlYXNlLAogIElBVklFZGl0U3RyZWFtX2ZuQ3V0LAogIElBVklFZGl0U3RyZWFtX2ZuQ29weSwKICBJQVZJRWRpdFN0cmVhbV9mblBhc3RlLAogIElBVklFZGl0U3RyZWFtX2ZuQ2xvbmUsCiAgSUFWSUVkaXRTdHJlYW1fZm5TZXRJbmZvCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLExPTkcqYnl0ZXNyZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcHdyaXR0ZW4sTE9ORypieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGllZGl0c3Rhc3QgPSB7CiAgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZiwKICBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5JbmZvLAogIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkLAogIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZihJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsTFBWT0lEKnBwaW1wbCk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElFZGl0U3RyZWFtSW50ZXJuYWxWdGJsIGllZGl0c3RyZWFtaW50ZXJuYWwgPSB7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblF1ZXJ5SW50ZXJmYWNlLAogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5BZGRSZWYsCiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblJlbGVhc2UsCiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSUVkaXRTdHJlYW1JbXBsIElBVklFZGl0U3RyZWFtSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JRWRpdEFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklFZGl0U3RyZWFtSW1wbCAqcGFlOwp9IElFZGl0QVZJU3RyZWFtSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JRWRpdFN0cmVhbUludGVybmFsSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJRWRpdFN0cmVhbUludGVybmFsVnRibCAqbHBWdGJsOwoKICAvKiBJRWRpdFN0cmVhbUludGVybmFsIHN0dWZmICovCiAgSUFWSUVkaXRTdHJlYW1JbXBsICpwYWU7Cn0gSUVkaXRTdHJlYW1JbnRlcm5hbEltcGw7CgpzdHJ1Y3QgX0lBVklFZGl0U3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJRWRpdFN0cmVhbVZ0YmwgKmxwVnRibDsKICBMT05HICByZWY7CgogIC8qIElBVklFZGl0U3RyZWFtIHN0dWZmICovCiAgSUVkaXRBVklTdHJlYW1JbXBsICAgICAgaUFWSVN0cmVhbTsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCBpRWRpdFN0cmVhbUludGVybmFsOwoKICBBVklTVFJFQU1JTkZPVyAgICAgICBzSW5mbzsKCiAgRWRpdFN0cmVhbVRhYmxlICAgICAqcFN0cmVhbXM7CiAgRFdPUkQgICAgICAgICAgICAgICAgblN0cmVhbXM7ICAgLyogY3VycmVudCBmaWxsIGxldmVsIG9mIHBTdHJlYW1zIHRhYmxlICovCiAgRFdPUkQgICAgICAgICAgICAgICAgblRhYmxlU2l6ZTsgLyogc2l6ZSBvZiBwU3RyZWFtcyB0YWJsZSAqLwoKICBCT09MICAgICAgICAgICAgICAgICBiRGVjb21wcmVzczsKICBQQVZJU1RSRUFNICAgICAgICAgICBwQ3VyU3RyZWFtOwogIFBHRVRGUkFNRSAgICAgICAgICAgIHBnOyAgICAgICAgIC8qIElHZXRGcmFtZSBmb3IgcEN1clN0cmVhbSAqLwogIExQQklUTUFQSU5GT0hFQURFUiAgIGxwRnJhbWU7ICAgIC8qIGZyYW1lIG9mIHBDdXJTdHJlYW0gKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KClBBVklFRElUU1RSRUFNIEFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKnBlZGl0ID0gTlVMTDsKCiAgcGVkaXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklFZGl0U3RyZWFtSW1wbCkpOwogIGlmIChwZWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIHBlZGl0LT5scFZ0YmwgICAgICAgICAgICA9ICZpZWRpdHN0cmVhbTsKICBwZWRpdC0+aUFWSVN0cmVhbS5scFZ0YmwgPSAmaWVkaXRzdGFzdDsKICBwZWRpdC0+aUFWSVN0cmVhbS5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5scFZ0YmwgPSAmaWVkaXRzdHJlYW1pbnRlcm5hbDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+cmVmID0gMTsKCiAgSUFWSVN0cmVhbV9DcmVhdGUoKFBBVklTVFJFQU0pJnBlZGl0LT5pQVZJU3RyZWFtLChMUEFSQU0pcHN0cmVhbSwwKTsKCiAgcmV0dXJuIChQQVZJRURJVFNUUkVBTSlwZWRpdDsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMsCgkJCQkJIERXT1JEIHBvcyxQQVZJU1RSRUFNICpwcFN0cmVhbSwKCQkJCQkgRFdPUkQqIHN0cmVhbVBvcywKCQkJCQkgRFdPUkQqIHN0cmVhbU5yLEJPT0wgYkZpbmRTYW1wbGUpCnsKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVsdSwlcCwlcCwlcCwlZClcbiIsVGhpcyxwb3MscHBTdHJlYW0sc3RyZWFtUG9zLAogICAgICAgIHN0cmVhbU5yLGJGaW5kU2FtcGxlKTsKCiAgaWYgKHBvcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBwb3MgLT0gVGhpcy0+c0luZm8uZHdTdGFydDsKICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+blN0cmVhbXM7IG4rKykgewogICAgaWYgKHBvcyA8IFRoaXMtPnBTdHJlYW1zW25dLmR3TGVuZ3RoKSB7CiAgICAgICpwcFN0cmVhbSAgPSBUaGlzLT5wU3RyZWFtc1tuXS5wU3RyZWFtOwogICAgICAqc3RyZWFtUG9zID0gVGhpcy0+cFN0cmVhbXNbbl0uZHdTdGFydCArIHBvczsKICAgICAgaWYgKHN0cmVhbU5yICE9IE5VTEwpCiAgICAgICAgKnN0cmVhbU5yID0gbjsKCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9CiAgICBwb3MgLT0gVGhpcy0+cFN0cmVhbXNbbl0uZHdMZW5ndGg7CiAgfQogIGlmIChwb3MgPT0gMCAmJiBiRmluZFNhbXBsZSkgewogICAgKnBwU3RyZWFtICA9IFRoaXMtPnBTdHJlYW1zWy0tbl0ucFN0cmVhbTsKICAgICpzdHJlYW1Qb3MgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIG4pOwogICAgaWYgKHN0cmVhbU5yICE9IE5VTEwpCiAgICAgICpzdHJlYW1OciA9IG47CgogICAgVFJBQ0UoIiAtLSBwb3M9MCAmJiBiPTEgLT4gKCVwLCVsdSwlbHUpXG4iLCpwcFN0cmVhbSwgKnN0cmVhbVBvcywgbik7CiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICAqcHBTdHJlYW0gPSBOVUxMOwogICAgKnN0cmVhbVBvcyA9IDA7CiAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgKnN0cmVhbU5yID0gMDsKCiAgICBUUkFDRSgiIC0+IEVSUk9SIChOVUxMLDAsMClcbiIpOwogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICB9Cn0KCnN0YXRpYyBMUFZPSUQgQVZJRklMRV9SZWFkRnJhbWUoSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MpCnsKICBQR0VURlJBTUUgcGc7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixUaGlzLHBzdHJlYW0scG9zKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICAvKiBpZiBzdHJlYW0gY2hhbmdlcyBtYWtlIHN1cmUgdGhhdCBvbmx5IHBhbGV0dGUgY2hhbmdlcyAqLwogIGlmIChUaGlzLT5wQ3VyU3RyZWFtICE9IHBzdHJlYW0pIHsKICAgIHBnID0gQVZJU3RyZWFtR2V0RnJhbWVPcGVuKHBzdHJlYW0sIE5VTEwpOwogICAgaWYgKHBnID09IE5VTEwpCiAgICAgIHJldHVybiBOVUxMOwogICAgaWYgKFRoaXMtPnBnICE9IE5VTEwpIHsKICAgICAgaWYgKElHZXRGcmFtZV9TZXRGb3JtYXQocGcsIFRoaXMtPmxwRnJhbWUsIE5VTEwsIDAsIDAsIC0xLCAtMSkpIHsKICAgICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKHBnKTsKICAgICAgICBFUlIoIjogSUdldEZyYW1lX1NldEZvcm1hdCBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgICB9CiAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoVGhpcy0+cGcpOwogICAgfQogICAgVGhpcy0+cGcgICAgICAgICA9IHBnOwogICAgVGhpcy0+cEN1clN0cmVhbSA9IHBzdHJlYW07CiAgfQoKICAvKiBub3cgZ2V0IHRoZSBkZWNvbXByZXNzZWQgZnJhbWUgKi8KICBUaGlzLT5scEZyYW1lID0gQVZJU3RyZWFtR2V0RnJhbWUoVGhpcy0+cGcsIHBvcyk7CiAgaWYgKFRoaXMtPmxwRnJhbWUgIT0gTlVMTCkKICAgIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmxwRnJhbWUtPmJpU2l6ZUltYWdlOwoKICByZXR1cm4gVGhpcy0+bHBGcmFtZTsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZW1vdmVTdHJlYW0oSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLCBEV09SRCBucikKewogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChuciA8IFRoaXMtPm5TdHJlYW1zKTsKCiAgLyogcmVtb3ZlIHBhcnQgbnIgKi8KICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbXNbbnJdLnBTdHJlYW0pOwogIFRoaXMtPm5TdHJlYW1zLS07CiAgaWYgKFRoaXMtPm5TdHJlYW1zIC0gbnIgPiAwKSB7CiAgICBtZW1tb3ZlKFRoaXMtPnBTdHJlYW1zICsgbnIsIFRoaXMtPnBTdHJlYW1zICsgbnIgKyAxLAogICAgICAgICAgICAoVGhpcy0+blN0cmVhbXMgLSBucikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgfQogIFRoaXMtPnBTdHJlYW1zW1RoaXMtPm5TdHJlYW1zXS5wU3RyZWFtICA9IE5VTEw7CiAgVGhpcy0+cFN0cmVhbXNbVGhpcy0+blN0cmVhbXNdLmR3U3RhcnQgID0gMDsKICBUaGlzLT5wU3RyZWFtc1tUaGlzLT5uU3RyZWFtc10uZHdMZW5ndGggPSAwOwoKICAvKiB0cnkgdG8gbWVyZ2UgdGhlIHBhcnQgYmVmb3JlIHRoZSBkZWxldGVkIG9uZSBhbmQgdGhlIG9uZSBhZnRlciBpdCAqLwogIGlmICgwIDwgbnIgJiYgMCA8IFRoaXMtPm5TdHJlYW1zICYmCiAgICAgIFRoaXMtPnBTdHJlYW1zW25yIC0gMV0ucFN0cmVhbSA9PSBUaGlzLT5wU3RyZWFtc1tucl0ucFN0cmVhbSkgewogICAgaWYgKEVkaXRTdHJlYW1FbmQoVGhpcywgbnIgLSAxKSA9PSBUaGlzLT5wU3RyZWFtc1tucl0uZHdTdGFydCkgewogICAgICBUaGlzLT5wU3RyZWFtc1tuciAtIDFdLmR3TGVuZ3RoICs9IFRoaXMtPnBTdHJlYW1zW25yXS5kd0xlbmd0aDsKICAgICAgcmV0dXJuIEFWSUZJTEVfUmVtb3ZlU3RyZWFtKFRoaXMsIG5yKTsKICAgIH0KICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBCT09MIEFWSUZJTEVfRm9ybWF0c0VxdWFsKFBBVklTVFJFQU0gYXZpMSwgUEFWSVNUUkVBTSBhdmkyKQp7CiAgTFBWT0lEIGZtdDEgPSBOVUxMLCBmbXQyID0gTlVMTDsKICBMT05HIHNpemUxLCBzaXplMiwgc3RhcnQxLCBzdGFydDI7CiAgQk9PTCBzdGF0dXMgPSBGQUxTRTsKCiAgYXNzZXJ0KGF2aTEgIT0gTlVMTCAmJiBhdmkyICE9IE5VTEwpOwoKICAvKiBnZXQgc3RyZWFtIHN0YXJ0cyBhbmQgY2hlY2sgZm9ybWF0IHNpemVzICovCiAgc3RhcnQxID0gQVZJU3RyZWFtU3RhcnQoYXZpMSk7CiAgc3RhcnQyID0gQVZJU3RyZWFtU3RhcnQoYXZpMik7CiAgaWYgKEZBSUxFRChBVklTdHJlYW1Gb3JtYXRTaXplKGF2aTEsIHN0YXJ0MSwgJnNpemUxKSkpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKEZBSUxFRChBVklTdHJlYW1Gb3JtYXRTaXplKGF2aTIsIHN0YXJ0MiwgJnNpemUyKSkpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKHNpemUxICE9IHNpemUyKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBzaXplcyBtYXRjaCwgbm93IGdldCBmb3JtYXRzIGFuZCBjb21wYXJlIHRoZW0gKi8KICBmbXQxID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUxKTsKICBpZiAoZm10MSA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwogIGlmIChTVUNDRUVERUQoQVZJU3RyZWFtUmVhZEZvcm1hdChhdmkxLCBzdGFydDEsIGZtdDEsICZzaXplMSkpKSB7CiAgICBmbXQyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUxKTsKICAgIGlmIChmbXQyICE9IE5VTEwpIHsKICAgICAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KGF2aTIsIHN0YXJ0MiwgZm10MiwgJnNpemUxKSkpCiAgICAgICAgc3RhdHVzID0gKG1lbWNtcChmbXQxLCBmbXQyLCBzaXplMSkgPT0gMCk7CiAgICB9CiAgfQoKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBmbXQyKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBmbXQxKTsKCiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUVkaXRTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaikKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRWRpdFN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgSUFWSUVkaXRTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pQVZJU3RyZWFtOwogICAgSUFWSUVkaXRTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSUVkaXRTdHJlYW1JbnRlcm5hbCwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pRWRpdFN0cmVhbUludGVybmFsOwogICAgSUFWSUVkaXRTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQWRkUmVmKElBVklFZGl0U3RyZWFtKmlmYWNlKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5SZWxlYXNlKElBVklFZGl0U3RyZWFtKmlmYWNlKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIERXT1JEIGk7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIHJlZik7CgogIGlmICghcmVmKSB7CiAgICAvKiByZWxlYXNlIG1lbW9yeSAqLwogICAgaWYgKFRoaXMtPnBnICE9IE5VTEwpCiAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoVGhpcy0+cGcpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zICE9IE5VTEwpIHsKICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPm5TdHJlYW1zOyBpKyspIHsKICAgICAgICBpZiAoVGhpcy0+cFN0cmVhbXNbaV0ucFN0cmVhbSAhPSBOVUxMKQogICAgICAgICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW1zW2ldLnBTdHJlYW0pOwogICAgICB9CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBTdHJlYW1zKTsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DdXQoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIFBBVklTVFJFQU0gc3RyZWFtOwogIERXT1JEICAgICAgc3RhcnQsIGxlbiwgc3RyZWFtUG9zLCBzdHJlYW1OcjsKICBIUkVTVUxUICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ICE9IE5VTEwpCiAgICAqcHBSZXN1bHQgPSBOVUxMOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCAqcGxTdGFydCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBpZiBhc2tlZCBmb3IgY3V0dGVkIHBhcnQgY29weSBpdCBiZWZvcmUgZGVsZXRpbmcgKi8KICBpZiAocHBSZXN1bHQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9Db3B5KGlmYWNlLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIHN0YXJ0ID0gKnBsU3RhcnQ7CiAgbGVuICAgPSAqcGxMZW5ndGg7CgogIC8qIG5vdyBkZWxldGUgdGhlIHJlcXVlc3RlZCBwYXJ0ICovCiAgd2hpbGUgKGxlbiA+IDApIHsKICAgIGhyID0gQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBzdGFydCwgJnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtUG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgPT0gc3RyZWFtUG9zKSB7CiAgICAgIC8qIGRlbGV0aW5nIGZyb20gc3RhcnQgb2YgcGFydCAqLwogICAgICBpZiAobGVuIDwgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoKSB7CiAgICAgICAgc3RhcnQgKz0gbGVuOwogICAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICArPSBsZW47CiAgICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoIC09IGxlbjsKICAgICAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBsZW47CiAgICAgICAgbGVuID0gMDsKCiAgICAgICAgLyogd2UgbXVzdCByZXR1cm4gZGVjb21wcmVzc2VkIGRhdGEgbm93ICovCiAgICAgICAgVGhpcy0+YkRlY29tcHJlc3MgPSBUUlVFOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIGRlbGV0aW5nIGhvbGUgcGFydCAqLwogICAgICAgIGxlbiAtPSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CiAgICAgICAgQVZJRklMRV9SZW1vdmVTdHJlYW0oVGhpcyxzdHJlYW1Ocik7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgPD0gc3RyZWFtUG9zICsgbGVuKSB7CiAgICAgIC8qIGRlbGV0aW5nIGF0IGVuZCBvZiBhIHBhcnQgKi8KICAgICAgRFdPUkQgY291bnQgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIHN0cmVhbVBvczsKICAgICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gY291bnQ7CiAgICAgIGxlbiAgICAgICAgICAgICAgICAgIC09IGNvdW50OwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQogICAgICAgIHN0cmVhbVBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgfSBlbHNlIHsKICAgICAgLyogc3BsaXR0aW5nICovCiAgICAgIGlmIChUaGlzLT5uU3RyZWFtcyArIDEgPj0gVGhpcy0+blRhYmxlU2l6ZSkgewogICAgICAgIFRoaXMtPnBTdHJlYW1zID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+cFN0cmVhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+blRhYmxlU2l6ZSArIDMyKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgICAgICBpZiAoVGhpcy0+cFN0cmVhbXMgPT0gTlVMTCkKICAgICAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICAgIFRoaXMtPm5UYWJsZVNpemUgKz0gMzI7CiAgICAgIH0KICAgICAgbWVtbW92ZShUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yICsgMSwgVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciwKICAgICAgICAgICAgICAoVGhpcy0+blN0cmVhbXMgLSBzdHJlYW1OcikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICAgIFRoaXMtPm5TdHJlYW1zKys7CgogICAgICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLnBTdHJlYW0pOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLmR3U3RhcnQgID0gc3RyZWFtUG9zICsgbGVuOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLmR3TGVuZ3RoID0KICAgICAgICBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgMV0uZHdTdGFydDsKCiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCA9CiAgICAgICAgc3RyZWFtUG9zIC0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQ7CiAgICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC09IGxlbjsKICAgICAgbGVuID0gMDsKICAgIH0KICB9CgogIFRoaXMtPnNJbmZvLmR3RWRpdENvdW50Kys7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkNvcHkoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSpwcFJlc3VsdCkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBJQVZJRWRpdFN0cmVhbUltcGwqIHBFZGl0OwogIEhSRVNVTFQgaHI7CiAgTE9ORyBzdGFydCA9IDA7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLGlmYWNlLHBsU3RhcnQscGxMZW5ndGgscHBSZXN1bHQpOwoKICBpZiAocHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgKnBwUmVzdWx0ID0gTlVMTDsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8IHBsTGVuZ3RoID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwIHx8ICpwbExlbmd0aCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBjaGVjayBib3VuZHMgKi8KICBpZiAoKihMUERXT1JEKXBsTGVuZ3RoID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICAqKExQRFdPUkQpcGxMZW5ndGggPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBpZiAoKihMUERXT1JEKXBsU3RhcnQgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KSB7CiAgICAqKExQRFdPUkQpcGxMZW5ndGggLT0gVGhpcy0+c0luZm8uZHdTdGFydCAtICooTFBEV09SRClwbFN0YXJ0OwogICAgKihMUERXT1JEKXBsU3RhcnQgICA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBpZiAoKnBsTGVuZ3RoIDwgMCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICB9CiAgaWYgKCooTFBEV09SRClwbFN0YXJ0ICsgKihMUERXT1JEKXBsTGVuZ3RoID4gVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgKihMUERXT1JEKXBsTGVuZ3RoID0gVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0KICAgICAgKihMUERXT1JEKXBsU3RhcnQ7CgogIHBFZGl0ID0gKElBVklFZGl0U3RyZWFtSW1wbCopQVZJRklMRV9DcmVhdGVFZGl0U3RyZWFtKE5VTEwpOwogIGlmIChwRWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGhyID0gSUFWSUVkaXRTdHJlYW1fUGFzdGUoKFBBVklFRElUU1RSRUFNKXBFZGl0LCZzdGFydCxwbExlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCpwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKnBsU3RhcnQgKyAqcGxMZW5ndGgpOwogICpwbFN0YXJ0ID0gc3RhcnQ7CiAgaWYgKEZBSUxFRChocikpCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKChQQVZJRURJVFNUUkVBTSlwRWRpdCk7CiAgZWxzZQogICAgKnBwUmVzdWx0ID0gKFBBVklTVFJFQU0pJnBFZGl0LT5pQVZJU3RyZWFtOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblBhc3RlKElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNIHBTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgbFN0YXJ0LExPTkcgbExlbmd0aCkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBBVklTVFJFQU1JTkZPVyAgICAgIHNyY0luZm87CiAgSUVkaXRTdHJlYW1JbnRlcm5hbCpwSW50ZXJuYWwgPSBOVUxMOwogIElBVklFZGl0U3RyZWFtSW1wbCAqcEVkaXQgPSBOVUxMOwogIFBBVklTVFJFQU0gICAgICAgICAgcFN0cmVhbTsKICBEV09SRCAgICAgICAgICAgICAgIHN0YXJ0UG9zLCBlbmRQb3MsIHN0cmVhbU5yLCBuU3RyZWFtczsKICBVTE9ORyAgICAgICAgICAgICAgIG47CgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJWxkLCVsZClcbiIsaWZhY2UscGxTdGFydCxwbExlbmd0aCwKCXBTb3VyY2UsbFN0YXJ0LGxMZW5ndGgpOwoKICBpZiAocFNvdXJjZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCAqcGxTdGFydCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPCAqcGxTdGFydCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07IC8qIENhbid0IHBhc3RlIHdpdGggaG9sZXMgKi8KICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwU291cmNlLCAmc3JjSW5mbywgc2l6ZW9mKHNyY0luZm8pKSkpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwogIGlmIChsU3RhcnQgPCBzcmNJbmZvLmR3U3RhcnQgfHwgbFN0YXJ0ID49IHNyY0luZm8uZHdTdGFydCArIHNyY0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IDApIHsKICAgIC8qIFRoaXMgc3RyZWFtIGlzIGVtcHR5ICovCiAgICBJQVZJU3RyZWFtX0luZm8ocFNvdXJjZSwgJlRoaXMtPnNJbmZvLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKICAgIFRoaXMtPnNJbmZvLmR3U3RhcnQgID0gKnBsU3RhcnQ7CiAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCA9IDA7CiAgfQogIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlICE9IHNyY0luZm8uZmNjVHlwZSkKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIGRpZmZlcmVudCBzdHJlYW0gdHlwZXMgKi8KICBpZiAobExlbmd0aCA9PSAtMSkgLyogQ29weSB0aGUgaG9sZSBzdHJlYW0gKi8KICAgIGxMZW5ndGggPSBzcmNJbmZvLmR3TGVuZ3RoOwogIGlmIChsU3RhcnQgKyBsTGVuZ3RoID4gc3JjSW5mby5kd1N0YXJ0ICsgc3JjSW5mby5kd0xlbmd0aCkKICAgIGxMZW5ndGggPSBzcmNJbmZvLmR3U3RhcnQgKyBzcmNJbmZvLmR3TGVuZ3RoIC0gbFN0YXJ0OwogIGlmIChsTGVuZ3RoICsgKnBsU3RhcnQgPj0gMHg4MDAwMDAwMCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBzdHJlYW10eXBlIHNwZWNpZmljIHRlc3RzICovCiAgaWYgKHNyY0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgIExPTkcgc2l6ZTsKCiAgICBzaXplID0gc3JjSW5mby5yY0ZyYW1lLnJpZ2h0IC0gc3JjSW5mby5yY0ZyYW1lLmxlZnQ7CiAgICBpZiAoc2l6ZSAhPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0IC0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0KQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBGSVhNRTogQ2FuJ3QgR2V0RnJhbWUgY29udmVydCBpdD8gKi8KICAgIHNpemUgPSBzcmNJbmZvLnJjRnJhbWUuYm90dG9tIC0gc3JjSW5mby5yY0ZyYW1lLnRvcDsKICAgIGlmIChzaXplICE9IFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tIC0gVGhpcy0+c0luZm8ucmNGcmFtZS50b3ApCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIEZJWE1FOiBDYW4ndCBHZXRGcmFtZSBjb252ZXJ0IGl0PyAqLwogIH0gZWxzZSBpZiAoc3JjSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykgewogICAgaWYgKCEgQVZJRklMRV9Gb3JtYXRzRXF1YWwoKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW0sIHBTb3VyY2UpKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0gZWxzZSB7CiAgICAvKiBGSVhNRTogc3RyZWFtdHlwZU1JREkgYW5kIHN0cmVhbXR5cGVURVhUICovCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogdHJ5IHRvIGdldCBhbiBJRWRpdFN0cmVhbUludGVybmFsIGludGVyZmFjZSAqLwogIGlmIChTVUNDRUVERUQoSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU291cmNlLCAmSUlEX0lFZGl0U3RyZWFtSW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQqKSZwSW50ZXJuYWwpKSkgewogICAgcEludGVybmFsLT5scFZ0YmwtPkdldEVkaXRTdHJlYW1JbXBsKHBJbnRlcm5hbCwgKExQVk9JRCopJnBFZGl0KTsKICAgIHBJbnRlcm5hbC0+bHBWdGJsLT5SZWxlYXNlKHBJbnRlcm5hbCk7CiAgfQoKICAvKiBmb3IgdmlkZW8gbXVzdCBjaGVjayBmb3IgY2hhbmdlIG9mIGZvcm1hdCAqLwogIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgaWYgKCEgVGhpcy0+YkRlY29tcHJlc3MpIHsKICAgICAgLyogTmVlZCB0byBkZWNvbXByZXNzIGlmIGFueSBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgbWF0Y2hlczoKICAgICAgICogIC0gcFNvdXJjZSBpcyBhbiBlZGl0YWJsZSBzdHJlYW0gd2hpY2ggZGVjb21wcmVzc2VzCiAgICAgICAqICAtIHRoZSBuZWFyZXN0IGtleWZyYW1lIG9mIHBTb3VyY2UgaXNuJ3QgbFN0YXJ0CiAgICAgICAqICAtIHRoZSBuZWFyZXN0IGtleWZyYW1lIG9mIHRoaXMgc3RyZWFtIGlzbid0ICpwbFN0YXJ0CiAgICAgICAqICAtIHRoZSBmb3JtYXQgb2YgcFNvdXJjZSBkb2Vzbid0IG1hdGNoIHRoaXMgb25lCiAgICAgICAqLwogICAgICBpZiAoKHBFZGl0ICE9IE5VTEwgJiYgcEVkaXQtPmJEZWNvbXByZXNzKSB8fAoJICBBVklTdHJlYW1OZWFyZXN0S2V5RnJhbWUocFNvdXJjZSwgbFN0YXJ0KSAhPSBsU3RhcnQgfHwKCSAgQVZJU3RyZWFtTmVhcmVzdEtleUZyYW1lKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCAqcGxTdGFydCkgIT0gKnBsU3RhcnQgfHwKCSAgKFRoaXMtPm5TdHJlYW1zID4gMCAmJiAhQVZJRklMRV9Gb3JtYXRzRXF1YWwoKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW0sIHBTb3VyY2UpKSkgewoJLyogVXNlIGZpcnN0IHN0cmVhbSBwYXJ0IHRvIGdldCBmb3JtYXQgdG8gY29udmVydCBldmVyeXRoaW5nIHRvICovCglBVklGSUxFX1JlYWRGcmFtZShUaGlzLCBUaGlzLT5wU3RyZWFtc1swXS5wU3RyZWFtLAoJCQkgIFRoaXMtPnBTdHJlYW1zWzBdLmR3U3RhcnQpOwoKCS8qIENoZWNrIGlmIHdlIGNvdWxkIGNvbnZlcnQgdGhlIHNvdXJjZSBzdHJlYW1zIHRvIHRoZSBkaXNpcmVkIGZvcm1hdC4uLiAqLwoJaWYgKHBFZGl0ICE9IE5VTEwpIHsKCSAgaWYgKEZBSUxFRChBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKHBFZGl0LCBsU3RhcnQsICZwU3RyZWFtLAoJCQkJCSAgICAgICAmc3RhcnRQb3MsICZzdHJlYW1OciwgVFJVRSkpKQoJICAgIHJldHVybiBBVklFUlJfSU5URVJOQUw7CgkgIGZvciAobiA9IGxTdGFydDsgbiA8IGxTdGFydCArIGxMZW5ndGg7IHN0cmVhbU5yKyspIHsKCSAgICBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcEVkaXQtPnBTdHJlYW1zW3N0cmVhbU5yXS5wU3RyZWFtLCBzdGFydFBvcykgPT0gTlVMTCkKCSAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoJICAgIHN0YXJ0UG9zID0gcEVkaXQtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwoJICAgIG4gKz0gcEVkaXQtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aDsKCSAgfQoJfSBlbHNlIGlmIChBVklGSUxFX1JlYWRGcmFtZShUaGlzLCBwU291cmNlLCBsU3RhcnQpID09IE5VTEwpCgkgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKCVRoaXMtPmJEZWNvbXByZXNzICAgICAgPSBUUlVFOwoJVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9IDA7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcFNvdXJjZSwgbFN0YXJ0KSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsgLyogQ2FuJ3QgY29udmVydCBzb3VyY2UgdG8gb3duIGZvcm1hdCAqLwogIH0gLyogRklYTUU6IHNvbWV0aGluZyBzcGVjaWFsIGZvciB0aGUgb3RoZXIgZm9ybWF0cz8gKi8KCiAgLyogTWFrZSBzdXJlIHdlIGhhdmUgZW5vdWdoIG1lbW9yeSBmb3IgcGFydHMgKi8KICBpZiAocEVkaXQgIT0gTlVMTCkgewogICAgRFdPUkQgbkxhc3RTdHJlYW07CgogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0ICsgbExlbmd0aCwgJnBTdHJlYW0sCgkJCSAgICAgICZlbmRQb3MsICZuTGFzdFN0cmVhbSwgVFJVRSk7CiAgICBBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKHBFZGl0LCBsU3RhcnQsICZwU3RyZWFtLAoJCQkgICAgICAmc3RhcnRQb3MsICZzdHJlYW1OciwgRkFMU0UpOwogICAgaWYgKG5MYXN0U3RyZWFtID09IHN0cmVhbU5yKQogICAgICBuTGFzdFN0cmVhbSsrOwoKICAgIG5TdHJlYW1zID0gbkxhc3RTdHJlYW0gLSBzdHJlYW1OcjsKICB9IGVsc2UgCiAgICBuU3RyZWFtcyA9IDE7CiAgaWYgKFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgKyAxID4gVGhpcy0+blRhYmxlU2l6ZSkgewogICAgbiA9IFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgKyAzMzsKCiAgICBUaGlzLT5wU3RyZWFtcyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPnBTdHJlYW1zLCBuICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+blRhYmxlU2l6ZSA9IG47CiAgfQoKICBpZiAocGxMZW5ndGggIT0gTlVMTCkKICAgICpwbExlbmd0aCA9IGxMZW5ndGg7CgogIC8qIG5vdyBkbyB0aGUgcmVhbCB3b3JrICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA+ICpwbFN0YXJ0KSB7CiAgICBBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKFRoaXMsICpwbFN0YXJ0LCAmcFN0cmVhbSwKCQkJICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChzdGFydFBvcyAhPSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydCkgewogICAgICAvKiBzcGxpdCBzdHJlYW0gc3RyZWFtTnIgYXQgc3RhcnRQb3MgKi8KICAgICAgbWVtbW92ZShUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yICsgblN0cmVhbXMgKyAxLAoJICAgICAgVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciwKCSAgICAgIChUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zIC0gc3RyZWFtTnIgKyAxKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKCiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgMl0uZHdMZW5ndGggPQoJRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OciArIDIpIC0gc3RhcnRQb3M7CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgMl0uZHdTdGFydCA9IHN0YXJ0UG9zOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQoJc3RhcnRQb3MgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKICAgICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLnBTdHJlYW0pOwogICAgICBzdHJlYW1OcisrOwogICAgfSBlbHNlIHsKICAgICAgLyogaW5zZXJ0IGJlZm9yZSBzdHJlYW0gYXQgc3RyZWFtTnIgKi8KICAgICAgbWVtbW92ZShUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yICsgblN0cmVhbXMsIFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsCgkgICAgICAoVGhpcy0+blN0cmVhbXMgKyBuU3RyZWFtcyAtIHN0cmVhbU5yKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgIH0KICB9IGVsc2UgLyogYXBwZW5kIHRoZSBzdHJlYW1zICovCiAgICBzdHJlYW1OciA9IFRoaXMtPm5TdHJlYW1zOwoKICBpZiAocEVkaXQgIT0gTlVMTCkgewogICAgLyogaW5zZXJ0IHRoZSBwYXJ0cyBvZiB0aGUgZWRpdGFibGUgc3RyZWFtIGluc3RlYWQgb2YgaXRzZWxmICovCiAgICBBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKHBFZGl0LCBsU3RhcnQgKyBsTGVuZ3RoLCAmcFN0cmVhbSwKCQkJICAgICAgJmVuZFBvcywgTlVMTCwgRkFMU0UpOwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwgJnN0YXJ0UG9zLCAmbiwgRkFMU0UpOwoKICAgIG1lbWNweShUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yLCBwRWRpdC0+cFN0cmVhbXMgKyBuLAoJICAgblN0cmVhbXMgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgPCBzdGFydFBvcykgewogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQoJRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgLSBzdGFydFBvczsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgID0gc3RhcnRQb3M7CiAgICB9CiAgICBpZiAoZW5kUG9zIDwgRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OciArIG5TdHJlYW1zKSkKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyBuU3RyZWFtc10uZHdMZW5ndGggPQoJZW5kUG9zIC0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyBuU3RyZWFtc10uZHdTdGFydDsKICB9IGVsc2UgewogICAgLyogYSBzaW1wbGUgc3RyZWFtICovCiAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0ucFN0cmVhbSAgPSBwU291cmNlOwogICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgID0gbFN0YXJ0OwogICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0gbExlbmd0aDsKICB9CgogIGZvciAobiA9IDA7IG4gPCBuU3RyZWFtczsgbisrKSB7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIG5dLnBTdHJlYW0pOwogICAgaWYgKDAgPCBzdHJlYW1OciArIG4gJiYKCVRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgbiAtIDFdLnBTdHJlYW0gIT0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyBuXS5wU3RyZWFtKSB7CiAgICAgIFRoaXMtPnNJbmZvLmR3RmxhZ3MgfD0gQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTOwogICAgICBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50Kys7CiAgICB9CiAgfQogIFRoaXMtPnNJbmZvLmR3RWRpdENvdW50Kys7CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggKz0gbExlbmd0aDsKICBUaGlzLT5uU3RyZWFtcyArPSBuU3RyZWFtczsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ2xvbmUoSUFWSUVkaXRTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBVklTVFJFQU0qcHBSZXN1bHQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBwRWRpdDsKICBEV09SRCBpOwoKICBUUkFDRSgiKCVwLCVwKVxuIixpZmFjZSxwcFJlc3VsdCk7CgogIGlmIChwcFJlc3VsdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICAqcHBSZXN1bHQgPSBOVUxMOwoKICBwRWRpdCA9IChJQVZJRWRpdFN0cmVhbUltcGwqKUFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShOVUxMKTsKICBpZiAocEVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIGlmIChUaGlzLT5uU3RyZWFtcyA+IHBFZGl0LT5uVGFibGVTaXplKSB7CiAgICBwRWRpdC0+cFN0cmVhbXMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBwRWRpdC0+cFN0cmVhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5uU3RyZWFtcyAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgIGlmIChwRWRpdC0+cFN0cmVhbXMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBwRWRpdC0+blRhYmxlU2l6ZSA9IFRoaXMtPm5TdHJlYW1zOwogIH0KICBwRWRpdC0+blN0cmVhbXMgPSBUaGlzLT5uU3RyZWFtczsKICBtZW1jcHkocEVkaXQtPnBTdHJlYW1zLCBUaGlzLT5wU3RyZWFtcywKICAgICAgICAgVGhpcy0+blN0cmVhbXMgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgbWVtY3B5KCZwRWRpdC0+c0luZm8sJlRoaXMtPnNJbmZvLHNpemVvZihUaGlzLT5zSW5mbykpOwogIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5uU3RyZWFtczsgaSsrKSB7CiAgICBpZiAocEVkaXQtPnBTdHJlYW1zW2ldLnBTdHJlYW0gIT0gTlVMTCkKICAgICAgSUFWSVN0cmVhbV9BZGRSZWYocEVkaXQtPnBTdHJlYW1zW2ldLnBTdHJlYW0pOwogIH0KCiAgKnBwUmVzdWx0ID0gKFBBVklTVFJFQU0pJnBFZGl0LT5pQVZJU3RyZWFtOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5TZXRJbmZvKElBVklFZGl0U3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpLExPTkcgc2l6ZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLGlmYWNlLGFzaSxzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChhc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgIT0gc2l6ZW9mKEFWSVNUUkVBTUlORk9XKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKICBpZiAoYXNpLT5kd1NjYWxlID09IDAgfHwgYXNpLT5kd1JhdGUgPT0gMCB8fCAoTE9ORylhc2ktPmR3UXVhbGl0eSA8IC0xIHx8CiAgICAgIGFzaS0+ZHdRdWFsaXR5ID4gSUNRVUFMSVRZX0hJR0gpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICBUaGlzLT5zSW5mby53TGFuZ3VhZ2UgPSBhc2ktPndMYW5ndWFnZTsKICBUaGlzLT5zSW5mby53UHJpb3JpdHkgPSBhc2ktPndQcmlvcml0eTsKICBUaGlzLT5zSW5mby5kd1N0YXJ0ICAgPSBhc2ktPmR3U3RhcnQ7CiAgaWYgKGFzaS0+ZHdSYXRlICE9IDApCiAgICBUaGlzLT5zSW5mby5kd1JhdGUgID0gYXNpLT5kd1JhdGU7CiAgaWYgKGFzaS0+ZHdTY2FsZSAhPSAwKQogICAgVGhpcy0+c0luZm8uZHdTY2FsZSA9IGFzaS0+ZHdTY2FsZTsKICBpZiAoYXNpLT5kd1F1YWxpdHkgPD0gSUNRVUFMSVRZX0hJR0gpCiAgICBUaGlzLT5zSW5mby5kd1F1YWxpdHkgPSBJQ1FVQUxJVFlfSElHSDsKICBDb3B5UmVjdCgmVGhpcy0+c0luZm8ucmNGcmFtZSwgJmFzaS0+cmNGcmFtZSk7CiAgbWVtY3B5KCZUaGlzLT5zSW5mby5zek5hbWUsICZhc2ktPnN6TmFtZSwgc2l6ZW9mKGFzaS0+c3pOYW1lKSk7CiAgVGhpcy0+c0luZm8uZHdFZGl0Q291bnQrKzsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUscmVmaWlkLG9iaik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fQWRkUmVmKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKmlmYWNlKQp7CiAgSUVkaXRBVklTdHJlYW1JbXBsICpUaGlzID0gKElFZGl0QVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUmVsZWFzZSgoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWU7CgogIGlmIChsUGFyYW0yICE9IDApCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICBpZiAoVGhpcy0+cFN0cmVhbXMgPT0gTlVMTCkgewogICAgVGhpcy0+cFN0cmVhbXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgMjU2ICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+blRhYmxlU2l6ZSA9IDI1NjsKICB9CgogIGlmIChsUGFyYW0xICE9IDApIHsKICAgIElBVklTdHJlYW1fSW5mbygoUEFWSVNUUkVBTSlsUGFyYW0xLCAmVGhpcy0+c0luZm8sIHNpemVvZihUaGlzLT5zSW5mbykpOwogICAgSUFWSVN0cmVhbV9BZGRSZWYoKFBBVklTVFJFQU0pbFBhcmFtMSk7CiAgICBUaGlzLT5wU3RyZWFtc1swXS5wU3RyZWFtICA9IChQQVZJU1RSRUFNKWxQYXJhbTE7CiAgICBUaGlzLT5wU3RyZWFtc1swXS5kd1N0YXJ0ICA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBUaGlzLT5wU3RyZWFtc1swXS5kd0xlbmd0aCA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogICAgVGhpcy0+blN0cmVhbXMgPSAxOwogIH0KICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpCnsKICBJRWRpdEFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUVkaXRBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxwc2ksc2l6ZSk7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBpZiAoVGhpcy0+cGFlLT5iRGVjb21wcmVzcykKICAgIFRoaXMtPnBhZS0+c0luZm8uZmNjSGFuZGxlciA9IDA7CgogIG1lbWNweShwc2ksICZUaGlzLT5wYWUtPnNJbmZvLCBtaW4oKERXT1JEKXNpemUsIHNpemVvZihUaGlzLT5wYWUtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+cGFlLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HICAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGZsYWdzKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqIGNvbnN0KWlmYWNlKS0+cGFlOwogIFBBVklTVFJFQU0gc3RyZWFtOwogIERXT1JEICAgICAgc3RyZWFtUG9zLCBzdHJlYW1OcjsKCiAgVFJBQ0UoIiglcCwlbGQsMHglMDhsWClcbiIsaWZhY2UscG9zLGZsYWdzKTsKCiAgaWYgKGZsYWdzICYgRklORF9GUk9NX1NUQVJUKQogICAgcG9zID0gKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydDsKCiAgLyogb3V0c2lkZSBvZiBzdHJlYW0/ICovCiAgaWYgKHBvcyA8IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgfHwKICAgICAgKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCArIChMT05HKVRoaXMtPnNJbmZvLmR3TGVuZ3RoIDw9IHBvcykKICAgIHJldHVybiAtMTsKCiAgLyogbWFwIG91ciBwb3NpdGlvbiB0byBhIHN0cmVhbSBhbmQgcG9zaXRpb24gaW4gaXQgKi8KICBpZiAoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBwb3MsICZzdHJlYW0sICZzdHJlYW1Qb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0cmVhbU5yLCBUUlVFKSkKICAgIHJldHVybiAtMTsgLyogZG9lc24ndCBleGlzdCAqLwoKICBpZiAoVGhpcy0+YkRlY29tcHJlc3MpIHsKICAgIC8qIG9ubHkgb25lIHN0cmVhbSAtLSBmb3JtYXQgY2hhbmdlcyBvbmx5IGF0IHN0YXJ0ICovCiAgICBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkKICAgICAgcmV0dXJuIChmbGFncyAmIEZJTkRfTkVYVCA/IC0xIDogMCk7CgogICAgLyogRklYTUU6IG1hcCBwb3NpdGlvbnMgYmFjayB0byB1cyAqLwogICAgcmV0dXJuIElBVklTdHJlYW1fRmluZFNhbXBsZShzdHJlYW0sIHN0cmVhbVBvcywgZmxhZ3MpOwogIH0gZWxzZSB7CiAgICAvKiBhc3N1bWUgY2hhbmdlIG9mIGZvcm1hdCBldmVyeSBmcmFtZSAqLwogICAgcmV0dXJuIHBvczsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgZm9ybWF0LExPTkcqZm10c2l6ZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcyA9ICgoSUVkaXRBVklTdHJlYW1JbXBsKiBjb25zdClpZmFjZSktPnBhZTsKICBMUEJJVE1BUElORk9IRUFERVIgIGxwOwogIFBBVklTVFJFQU0gICAgICAgICAgc3RyZWFtOwogIERXT1JEICAgICAgICAgICAgICAgbjsKICBIUkVTVUxUICAgICAgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlcClcbiIsaWZhY2UscG9zLGZvcm1hdCxmbXRzaXplKTsKCiAgaWYgKGZtdHNpemUgPT0gTlVMTCB8fCBwb3MgPCBUaGlzLT5zSW5mby5kd1N0YXJ0IHx8CiAgICAgIFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8PSBwb3MpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBmaW5kIHN0cmVhbSBjb3JyZXNwb25kaW5nIHRvIHBvc2l0aW9uICovCiAgaHIgPSBBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKFRoaXMsIHBvcywgJnN0cmVhbSwgJm4sIE5VTEwsIEZBTFNFKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgaWYgKCEgVGhpcy0+YkRlY29tcHJlc3MpCiAgICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRm9ybWF0KHN0cmVhbSwgbiwgZm9ybWF0LCBmbXRzaXplKTsKCiAgbHAgPSAoTFBCSVRNQVBJTkZPSEVBREVSKUFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHN0cmVhbSwgbik7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwogIGlmIChscC0+YmlCaXRDb3VudCA8PSA4KSB7CiAgICBuICA9IChscC0+YmlDbHJVc2VkID4gMCA/IGxwLT5iaUNsclVzZWQgOiAxIDw8IGxwLT5iaUJpdENvdW50KTsKICAgIG4gKj0gc2l6ZW9mKFJHQlFVQUQpOwogIH0gZWxzZQogICAgbiA9IDA7CiAgbiArPSBscC0+YmlTaXplOwogIAogIG1lbWNweShmb3JtYXQsIGxwLCBtaW4oKExPTkcpbiwgKmZtdHNpemUpKTsKICBociA9ICgoTE9ORyluID4gKmZtdHNpemUgPyBBVklFUlJfQlVGRkVSVE9PU01BTEwgOiBBVklFUlJfT0spOwogICpmbXRzaXplID0gbjsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKQp7CiAgVFJBQ0UoIiglcCwlbGQsJXAsJWxkKVxuIixpZmFjZSxwb3MsZm9ybWF0LGZvcm1hdHNpemUpOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGJ1ZmZlcnNpemUsTE9ORypieXRlc3JlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypzYW1wbGVzcmVhZCkKewogIElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcyA9ICgoSUVkaXRBVklTdHJlYW1JbXBsKiBjb25zdClpZmFjZSktPnBhZTsKICBQQVZJU1RSRUFNIHN0cmVhbTsKICBEV09SRCAgIHN0cmVhbVBvcywgc3RyZWFtTnI7CiAgTE9ORyAgICByZWFkQnl0ZXMsIHJlYWRTYW1wbGVzLCBjb3VudDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKSAtLSAweCUwOGxYXG4iLGlmYWNlLHN0YXJ0LHNhbXBsZXMsCiAgICAgICAgYnVmZmVyLGJ1ZmZlcnNpemUsYnl0ZXNyZWFkLHNhbXBsZXNyZWFkLFRoaXMtPnNJbmZvLmZjY1R5cGUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwogIGlmIChidWZmZXJzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKICBpZiAoKERXT1JEKXN0YXJ0IDwgVGhpcy0+c0luZm8uZHdTdGFydCB8fAogICAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPCAoRFdPUkQpc3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBpZiAoISBUaGlzLT5iRGVjb21wcmVzcykgewogICAgLyogYXVkaW8gbGlrZSBkYXRhIC0tIHNhbXBsZS1iYXNlZCAqLwogICAgZG8gewogICAgICBpZiAoc2FtcGxlcyA9PSAwKQogICAgICAgIHJldHVybiBBVklFUlJfT0s7IC8qIG5vdGhpbmcgYXQgYWxsIG9yIGFscmVhZHkgZG9uZSAqLwoKICAgICAgaWYgKEZBSUxFRChBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKFRoaXMsIHN0YXJ0LCAmc3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0cmVhbVBvcywgJnN0cmVhbU5yLCBGQUxTRSkpKQogICAgICAgIHJldHVybiBBVklFUlJfRVJST1I7CgogICAgICAvKiBsaW1pdCB0byBlbmQgb2YgdGhlIHN0cmVhbSAqLwogICAgICBjb3VudCA9IHNhbXBsZXM7CiAgICAgIGlmIChzdHJlYW1Qb3MgKyBjb3VudCA+IEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpKQogICAgICAgIGNvdW50ID0gRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgLSBzdHJlYW1Qb3M7CgogICAgICBociA9IElBVklTdHJlYW1fUmVhZChzdHJlYW0sIHN0cmVhbVBvcywgY291bnQsIGJ1ZmZlciwgYnVmZmVyc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlYWRCeXRlcywgJnJlYWRTYW1wbGVzKTsKICAgICAgaWYgKEZBSUxFRChocikpCiAgICAgICAgcmV0dXJuIGhyOwogICAgICBpZiAocmVhZEJ5dGVzID09IDAgJiYgcmVhZFNhbXBsZXMgPT0gMCAmJiBjb3VudCAhPSAwKQogICAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7IC8qIGZvciBiYWQgc3RyZWFtIGltcGxlbWVudGF0aW9ucyAqLwoKICAgICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICAgKnNhbXBsZXNyZWFkICs9IHJlYWRTYW1wbGVzOwogICAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICAgKmJ5dGVzcmVhZCArPSByZWFkQnl0ZXM7CiAgICAgIGlmIChidWZmZXIgIT0gTlVMTCkgewogICAgICAgIGJ1ZmZlciA9ICgoTFBCWVRFKWJ1ZmZlcikrcmVhZEJ5dGVzOwogICAgICAgIGJ1ZmZlcnNpemUgICAgIC09IHJlYWRCeXRlczsKICAgICAgfQogICAgICBzdGFydCAgICs9IGNvdW50OwogICAgICBzYW1wbGVzIC09IGNvdW50OwogICAgfSB3aGlsZSAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID4gc3RhcnQpOwogIH0gZWxzZSB7CiAgICAvKiB2aWRlbyBsaWtlIGRhdGEgLS0gZnJhbWUtYmFzZWQgKi8KICAgIExQQklUTUFQSU5GT0hFQURFUiBscDsKCiAgICBpZiAoc2FtcGxlcyA9PSAwKQogICAgICByZXR1cm4gQVZJRVJSX09LOwoKICAgIGlmIChGQUlMRUQoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBzdGFydCwgJnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtUG9zLCAmc3RyZWFtTnIsIEZBTFNFKSkpCiAgICAgIHJldHVybiBBVklFUlJfRVJST1I7CgogICAgbHAgPSBBVklGSUxFX1JlYWRGcmFtZShUaGlzLCBzdHJlYW0sIHN0cmVhbVBvcyk7CiAgICBpZiAobHAgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgICBpZiAoYnVmZmVyICE9IE5VTEwpIHsKICAgICAgLyogbmVlZCBzaXplIG9mIGZvcm1hdCB0byBza2lwICovCiAgICAgIGlmIChscC0+YmlCaXRDb3VudCA8PSA4KSB7CiAgICAgICAgY291bnQgID0gbHAtPmJpQ2xyVXNlZCA+IDAgPyBscC0+YmlDbHJVc2VkIDogMSA8PCBscC0+YmlCaXRDb3VudDsKICAgICAgICBjb3VudCAqPSBzaXplb2YoUkdCUVVBRCk7CiAgICAgIH0gZWxzZQogICAgICAgIGNvdW50ID0gMDsKICAgICAgY291bnQgKz0gbHAtPmJpU2l6ZTsKCiAgICAgIGlmIChidWZmZXJzaXplIDwgbHAtPmJpU2l6ZUltYWdlKQogICAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICAgIG1lbWNweShidWZmZXIsIChMUEJZVEUpbHAgKyBjb3VudCwgbHAtPmJpU2l6ZUltYWdlKTsKICAgIH0KCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBscC0+YmlTaXplSW1hZ2U7CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gMTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypzYW1wd3JpdHRlbixMT05HKmJ5dGVzd3JpdHRlbikKewogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglMDhsWCwlcCwlcClcbiIsaWZhY2Usc3RhcnQsc2FtcGxlcyxidWZmZXIsCiAgICAgICAgYnVmZmVyc2l6ZSxmbGFncyxzYW1wd3JpdHRlbixieXRlc3dyaXR0ZW4pOwoKICAvKiBiZSBzdXJlIHJldHVybiBwYXJhbWV0ZXJzIGhhdmUgY29ycmVjdCB2YWx1ZXMgKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMpCnsKICBJRWRpdEFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUVkaXRBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLCVsZClcbiIsaWZhY2Usc3RhcnQsc2FtcGxlcyk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9DdXQoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUsJnN0YXJ0LCZzYW1wbGVzLE5VTEwpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwLExPTkcgKmxwcmVhZCkKewogIElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcyA9ICgoSUVkaXRBVklTdHJlYW1JbXBsKiBjb25zdClpZmFjZSktPnBhZTsKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJXApXG4iLGlmYWNlLGZjYyxscCxscHJlYWQpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwID09IE5VTEwgfHwgbHByZWFkID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBzaW1wbHkgYXNrIGV2ZXJ5IHN0cmVhbSBhbmQgcmV0dXJuIHRoZSBmaXJzdCBibG9jayBmb3VuZCAqLwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5uU3RyZWFtczsgbisrKSB7CiAgICBIUkVTVUxUIGhyID0gSUFWSVN0cmVhbV9SZWFkRGF0YShUaGlzLT5wU3RyZWFtc1tuXS5wU3RyZWFtLGZjYyxscCxscHJlYWQpOwoKICAgIGlmIChTVUNDRUVERUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICAqbHByZWFkID0gMDsKICByZXR1cm4gQVZJRVJSX05PREFUQTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwLExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlbGQpXG4iLGlmYWNlLGZjYyxscCxzaXplKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBsZW4pCnsKICBJRWRpdEFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUVkaXRBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxpbmZvLGxlbik7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9TZXRJbmZvKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlLGluZm8sbGVuKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5RdWVyeUludGVyZmFjZShJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaikKewogIElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICpUaGlzID0gKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9RdWVyeUludGVyZmFjZSgoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZihJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKQp7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKlRoaXMgPSAoSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX0FkZFJlZigoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSk7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUmVsZWFzZShJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKQp7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKlRoaXMgPSAoSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1JlbGVhc2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5HZXRFZGl0U3RyZWFtSW1wbChJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlLExQVk9JRCpwcGltcGwpCnsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqVGhpcyA9IChJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwKSAtPiAlcFxuIiwgaWZhY2UsIHBwaW1wbCwgVGhpcy0+cGFlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKICBhc3NlcnQocHBpbXBsICE9IE5VTEwpOwoKICAqcHBpbXBsID0gVGhpcy0+cGFlOwogIHJldHVybiBBVklFUlJfT0s7Cn0K