LyoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBpbnRlcm5hbCBpbnRlcmZhY2UgdG8gZ2V0IGFjY2VzcyB0byB0YWJsZSBvZiBzdHJlYW0gaW4gYW4gZWRpdGFibGUgc3RyZWFtICovCnR5cGVkZWYgc3RydWN0IElFZGl0U3RyZWFtSW50ZXJuYWwgSUVkaXRTdHJlYW1JbnRlcm5hbDsKCnR5cGVkZWYgc3RydWN0IF9FZGl0U3RyZWFtVGFibGUgewogIFBBVklTVFJFQU0gcFN0cmVhbTsgIC8qIHN0cmVhbSB3aGljaCBjb250YWlucyB0aGUgZGF0YSAqLwogIERXT1JEICAgICAgZHdTdGFydDsgIC8qIHdoZXJlIHN0YXJ0cyB0aGUgcGFydCB3aGljaCBpcyBhbHNvIG91ciAqLwogIERXT1JEICAgICAgZHdMZW5ndGg7IC8qIGhvdyBtYW55IGlzIGFsc28gaW4gdGhpcyBzdHJlYW0gKi8KfSBFZGl0U3RyZWFtVGFibGU7CgojZGVmaW5lIElOVEVSRkFDRSBJRWRpdFN0cmVhbUludGVybmFsCiNkZWZpbmUgSUVkaXRTdHJlYW1JbnRlcm5hbF9NRVRIT0RTIFwKICAgIElVbmtub3duX01FVEhPRFMgXAogICAgU1RETUVUSE9EKEdldEVkaXRTdHJlYW1JbXBsKShUSElTXyBMUFZPSUQqKSBQVVJFOwpERUNMQVJFX0lOVEVSRkFDRV8oSUVkaXRTdHJlYW1JbnRlcm5hbCwgSVVua25vd24pIHsgSUVkaXRTdHJlYW1JbnRlcm5hbF9NRVRIT0RTIH07CiN1bmRlZiBJTlRFUkZBQ0UKCiNkZWZpbmUgRWRpdFN0cmVhbUVuZChUaGlzLHN0cmVhbU5yKSAoKFRoaXMpLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydCArIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcyktPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklFZGl0U3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5BZGRSZWYoSUFWSUVkaXRTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5SZWxlYXNlKElBVklFZGl0U3RyZWFtKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ3V0KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSpwcFJlc3VsdCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkNvcHkoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSpwcFJlc3VsdCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblBhc3RlKElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNIHBTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgbFN0YXJ0LExPTkcgbEVuZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkNsb25lKElBVklFZGl0U3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVZJU1RSRUFNKnBwUmVzdWx0KTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuU2V0SW5mbyhJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSxMT05HIHNpemUpOwoKc3RydWN0IElBVklFZGl0U3RyZWFtVnRibCBpZWRpdHN0cmVhbSA9IHsKICBJQVZJRWRpdFN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklFZGl0U3RyZWFtX2ZuQWRkUmVmLAogIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZSwKICBJQVZJRWRpdFN0cmVhbV9mbkN1dCwKICBJQVZJRWRpdFN0cmVhbV9mbkNvcHksCiAgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZSwKICBJQVZJRWRpdFN0cmVhbV9mbkNsb25lLAogIElBVklFZGl0U3RyZWFtX2ZuU2V0SW5mbwp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgYnVmZmVyc2l6ZSxMT05HKmJ5dGVzcmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXB3cml0dGVuLExPTkcqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RydWN0IElBVklTdHJlYW1WdGJsIGllZGl0c3Rhc3QgPSB7CiAgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZiwKICBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5JbmZvLAogIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkLAogIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZihJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsTFBWT0lEKnBwaW1wbCk7CgpzdHJ1Y3QgSUVkaXRTdHJlYW1JbnRlcm5hbFZ0YmwgaWVkaXRzdHJlYW1pbnRlcm5hbCA9IHsKICBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZiwKICBJRWRpdFN0cmVhbUludGVybmFsX2ZuUmVsZWFzZSwKICBJRWRpdFN0cmVhbUludGVybmFsX2ZuR2V0RWRpdFN0cmVhbUltcGwKfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJRWRpdFN0cmVhbUltcGwgSUFWSUVkaXRTdHJlYW1JbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lFZGl0QVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJQVZJU3RyZWFtVnRibCAqbHBWdGJsOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgSUFWSUVkaXRTdHJlYW1JbXBsICpwYWU7Cn0gSUVkaXRBVklTdHJlYW1JbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lFZGl0U3RyZWFtSW50ZXJuYWxJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElFZGl0U3RyZWFtSW50ZXJuYWxWdGJsICpscFZ0Ymw7CgogIC8qIElFZGl0U3RyZWFtSW50ZXJuYWwgc3R1ZmYgKi8KICBJQVZJRWRpdFN0cmVhbUltcGwgKnBhZTsKfSBJRWRpdFN0cmVhbUludGVybmFsSW1wbDsKCnN0cnVjdCBfSUFWSUVkaXRTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElBVklFZGl0U3RyZWFtVnRibCAqbHBWdGJsOwogIERXT1JEICByZWY7CgogIC8qIElBVklFZGl0U3RyZWFtIHN0dWZmICovCiAgSUVkaXRBVklTdHJlYW1JbXBsICAgICAgaUFWSVN0cmVhbTsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCBpRWRpdFN0cmVhbUludGVybmFsOwoKICBBVklTVFJFQU1JTkZPVyAgICAgICBzSW5mbzsKCiAgRWRpdFN0cmVhbVRhYmxlICAgICAqcFN0cmVhbXM7CiAgRFdPUkQgICAgICAgICAgICAgICAgblN0cmVhbXM7ICAgLyogY3VycmVudCBmaWxsIGxldmVsIG9mIHBTdHJlYW1zIHRhYmxlICovCiAgRFdPUkQgICAgICAgICAgICAgICAgblRhYmxlU2l6ZTsgLyogc2l6ZSBvZiBwU3RyZWFtcyB0YWJsZSAqLwoKICBCT09MICAgICAgICAgICAgICAgICBiRGVjb21wcmVzczsKICBQQVZJU1RSRUFNICAgICAgICAgICBwQ3VyU3RyZWFtOwogIFBHRVRGUkFNRSAgICAgICAgICAgIHBnOyAgICAgICAgIC8qIElHZXRGcmFtZSBmb3IgcEN1clN0cmVhbSAqLwogIExQQklUTUFQSU5GT0hFQURFUiAgIGxwRnJhbWU7ICAgIC8qIGZyYW1lIG9mIHBDdXJTdHJlYW0gKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KClBBVklFRElUU1RSRUFNIEFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKnBlZGl0ID0gTlVMTDsKCiAgcGVkaXQgPSAoSUFWSUVkaXRTdHJlYW1JbXBsKilMb2NhbEFsbG9jKExQVFIsc2l6ZW9mKElBVklFZGl0U3RyZWFtSW1wbCkpOwogIGlmIChwZWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIHBlZGl0LT5scFZ0YmwgICAgICAgICAgICA9ICZpZWRpdHN0cmVhbTsKICBwZWRpdC0+aUFWSVN0cmVhbS5scFZ0YmwgPSAmaWVkaXRzdGFzdDsKICBwZWRpdC0+aUFWSVN0cmVhbS5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5scFZ0YmwgPSAmaWVkaXRzdHJlYW1pbnRlcm5hbDsKICBwZWRpdC0+aUVkaXRTdHJlYW1JbnRlcm5hbC5wYWUgICAgPSBwZWRpdDsKICBwZWRpdC0+cmVmID0gMTsKCiAgSUFWSVN0cmVhbV9DcmVhdGUoKFBBVklTVFJFQU0pJnBlZGl0LT5pQVZJU3RyZWFtLChMUEFSQU0pcHN0cmVhbSwwKTsKCiAgcmV0dXJuIChQQVZJRURJVFNUUkVBTSlwZWRpdDsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMsCgkJCQkJIERXT1JEIHBvcyxQQVZJU1RSRUFNICpwcFN0cmVhbSwKCQkJCQkgRFdPUkQqIHN0cmVhbVBvcywKCQkJCQkgRFdPUkQqIHN0cmVhbU5yLEJPT0wgYkZpbmRTYW1wbGUpCnsKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVsdSwlcCwlcCwlcCwlZClcbiIsVGhpcyxwb3MscHBTdHJlYW0sc3RyZWFtUG9zLAogICAgICAgIHN0cmVhbU5yLGJGaW5kU2FtcGxlKTsKCiAgaWYgKHBvcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBwb3MgLT0gVGhpcy0+c0luZm8uZHdTdGFydDsKICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+blN0cmVhbXM7IG4rKykgewogICAgaWYgKHBvcyA8IFRoaXMtPnBTdHJlYW1zW25dLmR3TGVuZ3RoKSB7CiAgICAgICpwcFN0cmVhbSAgPSBUaGlzLT5wU3RyZWFtc1tuXS5wU3RyZWFtOwogICAgICAqc3RyZWFtUG9zID0gVGhpcy0+cFN0cmVhbXNbbl0uZHdTdGFydCArIHBvczsKICAgICAgaWYgKHN0cmVhbU5yICE9IE5VTEwpCiAgICAgICAgKnN0cmVhbU5yID0gbjsKCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9CiAgICBwb3MgLT0gVGhpcy0+cFN0cmVhbXNbbl0uZHdMZW5ndGg7CiAgfQogIGlmIChwb3MgPT0gMCAmJiBiRmluZFNhbXBsZSkgewogICAgKnBwU3RyZWFtICA9IFRoaXMtPnBTdHJlYW1zWy0tbl0ucFN0cmVhbTsKICAgICpzdHJlYW1Qb3MgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIG4pOwogICAgaWYgKHN0cmVhbU5yICE9IE5VTEwpCiAgICAgICpzdHJlYW1OciA9IG47CgogICAgVFJBQ0UoIiAtLSBwb3M9MCAmJiBiPTEgLT4gKCVwLCVsdSwlbHUpXG4iLCpwcFN0cmVhbSwgKnN0cmVhbVBvcywgbik7CiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICAqcHBTdHJlYW0gPSBOVUxMOwogICAgKnN0cmVhbVBvcyA9IDA7CiAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgKnN0cmVhbU5yID0gMDsKCiAgICBUUkFDRSgiIC0+IEVSUk9SIChOVUxMLDAsMClcbiIpOwogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICB9Cn0KCnN0YXRpYyBMUFZPSUQgQVZJRklMRV9SZWFkRnJhbWUoSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MpCnsKICBQR0VURlJBTUUgcGc7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixUaGlzLHBzdHJlYW0scG9zKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICAvKiBpZiBzdHJlYW0gY2hhbmdlcyBtYWtlIHN1cmUgdGhhdCBvbmx5IHBhbGV0dGUgY2hhbmdlcyAqLwogIGlmIChUaGlzLT5wQ3VyU3RyZWFtICE9IHBzdHJlYW0pIHsKICAgIHBnID0gQVZJU3RyZWFtR2V0RnJhbWVPcGVuKHBzdHJlYW0sIE5VTEwpOwogICAgaWYgKHBnID09IE5VTEwpCiAgICAgIHJldHVybiBOVUxMOwogICAgaWYgKFRoaXMtPnBnICE9IE5VTEwpIHsKICAgICAgaWYgKElHZXRGcmFtZV9TZXRGb3JtYXQocGcsIFRoaXMtPmxwRnJhbWUsIE5VTEwsIDAsIDAsIC0xLCAtMSkpIHsKICAgICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKHBnKTsKICAgICAgICBFUlIoIjogSUdldEZyYW1lX1NldEZvcm1hdCBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgICB9CiAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoVGhpcy0+cGcpOwogICAgfQogICAgVGhpcy0+cGcgICAgICAgICA9IHBnOwogICAgVGhpcy0+cEN1clN0cmVhbSA9IHBzdHJlYW07CiAgfQoKICAvKiBub3cgZ2V0IHRoZSBkZWNvbXByZXNzZWQgZnJhbWUgKi8KICBUaGlzLT5scEZyYW1lID0gQVZJU3RyZWFtR2V0RnJhbWUoVGhpcy0+cGcsIHBvcyk7CiAgaWYgKFRoaXMtPmxwRnJhbWUgIT0gTlVMTCkKICAgIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmxwRnJhbWUtPmJpU2l6ZUltYWdlOwoKICByZXR1cm4gVGhpcy0+bHBGcmFtZTsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZW1vdmVTdHJlYW0oSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLCBEV09SRCBucikKewogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChuciA8IFRoaXMtPm5TdHJlYW1zKTsKCiAgLyogcmVtb3ZlIHBhcnQgbnIgKi8KICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbXNbbnJdLnBTdHJlYW0pOwogIFRoaXMtPm5TdHJlYW1zLS07CiAgaWYgKFRoaXMtPm5TdHJlYW1zIC0gbnIgPiAwKSB7CiAgICBtZW1tb3ZlKFRoaXMtPnBTdHJlYW1zICsgbnIsIFRoaXMtPnBTdHJlYW1zICsgbnIgKyAxLAogICAgICAgICAgICAoVGhpcy0+blN0cmVhbXMgLSBucikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgfQogIFRoaXMtPnBTdHJlYW1zW1RoaXMtPm5TdHJlYW1zXS5wU3RyZWFtICA9IE5VTEw7CiAgVGhpcy0+cFN0cmVhbXNbVGhpcy0+blN0cmVhbXNdLmR3U3RhcnQgID0gMDsKICBUaGlzLT5wU3RyZWFtc1tUaGlzLT5uU3RyZWFtc10uZHdMZW5ndGggPSAwOwoKICAvKiB0cnkgdG8gbWVyZ2UgdGhlIHBhcnQgYmVmb3JlIHRoZSBkZWxldGVkIG9uZSBhbmQgdGhlIG9uZSBhZnRlciBpdCAqLwogIGlmICgwIDwgbnIgJiYgMCA8IFRoaXMtPm5TdHJlYW1zICYmCiAgICAgIFRoaXMtPnBTdHJlYW1zW25yIC0gMV0ucFN0cmVhbSA9PSBUaGlzLT5wU3RyZWFtc1tucl0ucFN0cmVhbSkgewogICAgaWYgKEVkaXRTdHJlYW1FbmQoVGhpcywgbnIgLSAxKSA9PSBUaGlzLT5wU3RyZWFtc1tucl0uZHdTdGFydCkgewogICAgICBUaGlzLT5wU3RyZWFtc1tuciAtIDFdLmR3TGVuZ3RoICs9IFRoaXMtPnBTdHJlYW1zW25yXS5kd0xlbmd0aDsKICAgICAgcmV0dXJuIEFWSUZJTEVfUmVtb3ZlU3RyZWFtKFRoaXMsIG5yKTsKICAgIH0KICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBCT09MIEFWSUZJTEVfRm9ybWF0c0VxdWFsKFBBVklTVFJFQU0gYXZpMSwgUEFWSVNUUkVBTSBhdmkyKQp7CiAgTFBWT0lEIGZtdDEgPSBOVUxMLCBmbXQyID0gTlVMTDsKICBMT05HIHNpemUxLCBzaXplMiwgc3RhcnQxLCBzdGFydDI7CiAgQk9PTCBzdGF0dXMgPSBGQUxTRTsKCiAgYXNzZXJ0KGF2aTEgIT0gTlVMTCAmJiBhdmkyICE9IE5VTEwpOwoKICAvKiBnZXQgc3RyZWFtIHN0YXJ0cyBhbmQgY2hlY2sgZm9ybWF0IHNpemVzICovCiAgc3RhcnQxID0gQVZJU3RyZWFtU3RhcnQoYXZpMSk7CiAgc3RhcnQyID0gQVZJU3RyZWFtU3RhcnQoYXZpMik7CiAgaWYgKEZBSUxFRChBVklTdHJlYW1Gb3JtYXRTaXplKGF2aTEsIHN0YXJ0MSwgJnNpemUxKSkpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKEZBSUxFRChBVklTdHJlYW1Gb3JtYXRTaXplKGF2aTIsIHN0YXJ0MiwgJnNpemUyKSkpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKHNpemUxICE9IHNpemUyKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBzaXplcyBtYXRjaCwgbm93IGdldCBmb3JtYXRzIGFuZCBjb21wYXJlIHRoZW0gKi8KICBmbXQxID0gR2xvYmFsQWxsb2NQdHIoR0hORCwgc2l6ZTEpOwogIGlmIChmbXQxID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KGF2aTEsIHN0YXJ0MSwgZm10MSwgJnNpemUxKSkpIHsKICAgIGZtdDIgPSBHbG9iYWxBbGxvY1B0cihHSE5ELCBzaXplMSk7CiAgICBpZiAoZm10MiAhPSBOVUxMKSB7CiAgICAgIGlmIChTVUNDRUVERUQoQVZJU3RyZWFtUmVhZEZvcm1hdChhdmkyLCBzdGFydDIsIGZtdDIsICZzaXplMSkpKQogICAgICAgIHN0YXR1cyA9IChtZW1jbXAoZm10MSwgZm10Miwgc2l6ZTEpID09IDApOwogICAgfQogIH0KCiAgaWYgKGZtdDIgIT0gTlVMTCkKICAgIEdsb2JhbEZyZWVQdHIoZm10Mik7CiAgR2xvYmFsRnJlZVB0cihmbXQxKTsKCiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUVkaXRTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaikKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRWRpdFN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgSUFWSUVkaXRTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pQVZJU3RyZWFtOwogICAgSUFWSUVkaXRTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSUVkaXRTdHJlYW1JbnRlcm5hbCwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pRWRpdFN0cmVhbUludGVybmFsOwogICAgSUFWSUVkaXRTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQWRkUmVmKElBVklFZGl0U3RyZWFtKmlmYWNlKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgKyAxKTsKICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBEV09SRCBpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgLSAxKTsKCiAgaWYgKCEtLShUaGlzLT5yZWYpKSB7CiAgICAvKiByZWxlYWFzZSBtZW1vcnkgKi8KICAgIGlmIChUaGlzLT5wZyAhPSBOVUxMKQogICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKFRoaXMtPnBnKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtcyAhPSBOVUxMKSB7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5uU3RyZWFtczsgaSsrKSB7CiAgICAgICAgaWYgKFRoaXMtPnBTdHJlYW1zW2ldLnBTdHJlYW0gIT0gTlVMTCkKICAgICAgICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtc1tpXS5wU3RyZWFtKTsKICAgICAgfQogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPnBTdHJlYW1zKTsKICAgIH0KCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gVGhpcy0+cmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DdXQoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIFBBVklTVFJFQU0gc3RyZWFtOwogIERXT1JEICAgICAgc3RhcnQsIGxlbiwgc3RyZWFtUG9zLCBzdHJlYW1OcjsKICBIUkVTVUxUICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ICE9IE5VTEwpCiAgICAqcHBSZXN1bHQgPSBOVUxMOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCAqcGxTdGFydCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBpZiBhc2tlZCBmb3IgY3V0dGVkIHBhcnQgY29weSBpdCBiZWZvcmUgZGVsZXRpbmcgKi8KICBpZiAocHBSZXN1bHQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9Db3B5KGlmYWNlLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIHN0YXJ0ID0gKnBsU3RhcnQ7CiAgbGVuICAgPSAqcGxMZW5ndGg7CgogIC8qIG5vdyBkZWxldGUgdGhlIHJlcXVlc3RlZCBwYXJ0ICovCiAgd2hpbGUgKGxlbiA+IDApIHsKICAgIGhyID0gQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBzdGFydCwgJnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtUG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgPT0gc3RyZWFtUG9zKSB7CiAgICAgIC8qIGRlbGV0aW5nIGZyb20gc3RhcnQgb2YgcGFydCAqLwogICAgICBpZiAobGVuIDwgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoKSB7CiAgICAgICAgc3RhcnQgKz0gbGVuOwogICAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICArPSBsZW47CiAgICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoIC09IGxlbjsKICAgICAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBsZW47CiAgICAgICAgbGVuID0gMDsKCiAgICAgICAgLyogd2UgbXVzdCByZXR1cm4gZGVjb21wcmVzc2VkIGRhdGEgbm93ICovCiAgICAgICAgVGhpcy0+YkRlY29tcHJlc3MgPSBUUlVFOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIGRlbGV0aW5nIGhvbGUgcGFydCAqLwogICAgICAgIGxlbiAtPSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CiAgICAgICAgQVZJRklMRV9SZW1vdmVTdHJlYW0oVGhpcyxzdHJlYW1Ocik7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgPD0gc3RyZWFtUG9zICsgbGVuKSB7CiAgICAgIC8qIGRlbGV0aW5nIGF0IGVuZCBvZiBhIHBhcnQgKi8KICAgICAgRFdPUkQgY291bnQgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIHN0cmVhbVBvczsKICAgICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gY291bnQ7CiAgICAgIGxlbiAgICAgICAgICAgICAgICAgIC09IGNvdW50OwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQogICAgICAgIHN0cmVhbVBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgfSBlbHNlIHsKICAgICAgLyogc3BsaXR0aW5nICovCiAgICAgIGlmIChUaGlzLT5uU3RyZWFtcyArIDEgPj0gVGhpcy0+blRhYmxlU2l6ZSkgewogICAgICAgIFRoaXMtPnBTdHJlYW1zID0KICAgICAgICAgIEdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+cFN0cmVhbXMsIChUaGlzLT5uVGFibGVTaXplICsgMzIpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSksIEdNRU1fU0hBUkV8R0hORCk7CiAgICAgICAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgICBUaGlzLT5uVGFibGVTaXplICs9IDMyOwogICAgICB9CiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIDEsIFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsCiAgICAgICAgICAgICAgKFRoaXMtPm5TdHJlYW1zIC0gc3RyZWFtTnIpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgICBUaGlzLT5uU3RyZWFtcysrOwoKICAgICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5wU3RyZWFtKTsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5kd1N0YXJ0ICA9IHN0cmVhbVBvcyArIGxlbjsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5kd0xlbmd0aCA9CiAgICAgICAgRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLmR3U3RhcnQ7CgogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQogICAgICAgIHN0cmVhbVBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBsZW47CiAgICAgIGxlbiA9IDA7CiAgICB9CiAgfQoKICBUaGlzLT5zSW5mby5kd0VkaXRDb3VudCsrOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5Db3B5KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBwRWRpdDsKICBIUkVTVUxUIGhyOwogIExPTkcgc3RhcnQgPSAwOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogICpwcFJlc3VsdCA9IE5VTEw7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8ICpwbFN0YXJ0IDwgMCB8fCAqcGxMZW5ndGggPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY2hlY2sgYm91bmRzICovCiAgaWYgKCooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgKihMUERXT1JEKXBsTGVuZ3RoID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKCooTFBEV09SRClwbFN0YXJ0IDwgVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgKihMUERXT1JEKXBsTGVuZ3RoIC09IFRoaXMtPnNJbmZvLmR3U3RhcnQgLSAqKExQRFdPUkQpcGxTdGFydDsKICAgICooTFBEV09SRClwbFN0YXJ0ICAgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgaWYgKCpwbExlbmd0aCA8IDApCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgfQogIGlmICgqKExQRFdPUkQpcGxTdGFydCArICooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgICooTFBEV09SRClwbExlbmd0aCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCAtCiAgICAgICooTFBEV09SRClwbFN0YXJ0OwoKICBwRWRpdCA9IChJQVZJRWRpdFN0cmVhbUltcGwqKUFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShOVUxMKTsKICBpZiAocEVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IElBVklFZGl0U3RyZWFtX1Bhc3RlKChQQVZJRURJVFNUUkVBTSlwRWRpdCwmc3RhcnQscGxMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICpwbFN0YXJ0ICsgKnBsTGVuZ3RoKTsKICAqcGxTdGFydCA9IHN0YXJ0OwogIGlmIChGQUlMRUQoaHIpKQogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZSgoUEFWSUVESVRTVFJFQU0pcEVkaXQpOwogIGVsc2UKICAgICpwcFJlc3VsdCA9IChQQVZJU1RSRUFNKSZwRWRpdC0+aUFWSVN0cmVhbTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSBwU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGxTdGFydCxMT05HIGxMZW5ndGgpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgQVZJU1RSRUFNSU5GT1cgICAgICBzcmNJbmZvOwogIElFZGl0U3RyZWFtSW50ZXJuYWwqcEludGVybmFsID0gTlVMTDsKICBJQVZJRWRpdFN0cmVhbUltcGwgKnBFZGl0ID0gTlVMTDsKICBQQVZJU1RSRUFNICAgICAgICAgIHBTdHJlYW07CiAgRFdPUkQgICAgICAgICAgICAgICBzdGFydFBvcywgZW5kUG9zLCBzdHJlYW1OciwgblN0cmVhbXM7CiAgTE9ORyAgICAgICAgICAgICAgICBuOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVsZCwlbGQpXG4iLGlmYWNlLHBsU3RhcnQscGxMZW5ndGgsCglwU291cmNlLGxTdGFydCxsTGVuZ3RoKTsKCiAgaWYgKHBTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKnBsU3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOyAvKiBDYW4ndCBwYXN0ZSB3aXRoIGhvbGVzICovCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocFNvdXJjZSwgJnNyY0luZm8sIHNpemVvZihzcmNJbmZvKSkpKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICBpZiAobFN0YXJ0IDwgc3JjSW5mby5kd1N0YXJ0IHx8IGxTdGFydCA+PSBzcmNJbmZvLmR3U3RhcnQgKyBzcmNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSAwKSB7CiAgICAvKiBUaGlzIHN0cmVhbSBpcyBlbXB0eSAqLwogICAgSUFWSVN0cmVhbV9JbmZvKHBTb3VyY2UsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ICA9ICpwbFN0YXJ0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSAwOwogIH0KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzcmNJbmZvLmZjY1R5cGUpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBkaWZmZXJlbnQgc3RyZWFtIHR5cGVzICovCiAgaWYgKGxMZW5ndGggPT0gLTEpIC8qIENvcHkgdGhlIGhvbGUgc3RyZWFtICovCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd0xlbmd0aDsKICBpZiAobFN0YXJ0ICsgbExlbmd0aCA+IHNyY0luZm8uZHdTdGFydCArIHNyY0luZm8uZHdMZW5ndGgpCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd1N0YXJ0ICsgc3JjSW5mby5kd0xlbmd0aCAtIGxTdGFydDsKICBpZiAobExlbmd0aCArICpwbFN0YXJ0ID49IDB4ODAwMDAwMDApCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogc3RyZWFtdHlwZSBzcGVjaWZpYyB0ZXN0cyAqLwogIGlmIChzcmNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICBMT05HIHNpemU7CgogICAgc2l6ZSA9IHNyY0luZm8ucmNGcmFtZS5yaWdodCAtIHNyY0luZm8ucmNGcmFtZS5sZWZ0OwogICAgaWYgKHNpemUgIT0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogRklYTUU6IENhbid0IEdldEZyYW1lIGNvbnZlcnQgaXQ/ICovCiAgICBzaXplID0gc3JjSW5mby5yY0ZyYW1lLmJvdHRvbSAtIHNyY0luZm8ucmNGcmFtZS50b3A7CiAgICBpZiAoc2l6ZSAhPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBGSVhNRTogQ2FuJ3QgR2V0RnJhbWUgY29udmVydCBpdD8gKi8KICB9IGVsc2UgaWYgKHNyY0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKICAgIGlmICghIEFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UgewogICAgLyogRklYTUU6IHN0cmVhbXR5cGVNSURJIGFuZCBzdHJlYW10eXBlVEVYVCAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIHRyeSB0byBnZXQgYW4gSUVkaXRTdHJlYW1JbnRlcm5hbCBpbnRlcmZhY2UgKi8KICBpZiAoU1VDQ0VFREVEKElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFNvdXJjZSwgJklJRF9JRWRpdFN0cmVhbUludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKikmcEludGVybmFsKSkpIHsKICAgIHBJbnRlcm5hbC0+bHBWdGJsLT5HZXRFZGl0U3RyZWFtSW1wbChwSW50ZXJuYWwsIChMUFZPSUQqKSZwRWRpdCk7CiAgICBwSW50ZXJuYWwtPmxwVnRibC0+UmVsZWFzZShwSW50ZXJuYWwpOwogIH0KCiAgLyogZm9yIHZpZGVvIG11c3QgY2hlY2sgZm9yIGNoYW5nZSBvZiBmb3JtYXQgKi8KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAgIC8qIE5lZWQgdG8gZGVjb21wcmVzcyBpZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG1hdGNoZXM6CiAgICAgICAqICAtIHBTb3VyY2UgaXMgYW4gZWRpdGFibGUgc3RyZWFtIHdoaWNoIGRlY29tcHJlc3NlcwogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiBwU291cmNlIGlzbid0IGxTdGFydAogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiB0aGlzIHN0cmVhbSBpc24ndCAqcGxTdGFydAogICAgICAgKiAgLSB0aGUgZm9ybWF0IG9mIHBTb3VyY2UgZG9lc24ndCBtYXRjaCB0aGlzIG9uZQogICAgICAgKi8KICAgICAgaWYgKChwRWRpdCAhPSBOVUxMICYmIHBFZGl0LT5iRGVjb21wcmVzcykgfHwKCSAgQVZJU3RyZWFtTmVhcmVzdEtleUZyYW1lKHBTb3VyY2UsIGxTdGFydCkgIT0gbFN0YXJ0IHx8CgkgIEFWSVN0cmVhbU5lYXJlc3RLZXlGcmFtZSgoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwgKnBsU3RhcnQpICE9ICpwbFN0YXJ0IHx8CgkgIChUaGlzLT5uU3RyZWFtcyA+IDAgJiYgIUFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkpIHsKCS8qIFVzZSBmaXJzdCBzdHJlYW0gcGFydCB0byBnZXQgZm9ybWF0IHRvIGNvbnZlcnQgZXZlcnl0aGluZyB0byAqLwoJQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgVGhpcy0+cFN0cmVhbXNbMF0ucFN0cmVhbSwKCQkJICBUaGlzLT5wU3RyZWFtc1swXS5kd1N0YXJ0KTsKCgkvKiBDaGVjayBpZiB3ZSBjb3VsZCBjb252ZXJ0IHRoZSBzb3VyY2Ugc3RyZWFtcyB0byB0aGUgZGlzaXJlZCBmb3JtYXQuLi4gKi8KCWlmIChwRWRpdCAhPSBOVUxMKSB7CgkgIGlmIChGQUlMRUQoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJCQkgICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIFRSVUUpKSkKCSAgICByZXR1cm4gQVZJRVJSX0lOVEVSTkFMOwoJICBmb3IgKG4gPSBsU3RhcnQ7IG4gPCBsU3RhcnQgKyBsTGVuZ3RoOyBzdHJlYW1OcisrKSB7CgkgICAgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0ucFN0cmVhbSwgc3RhcnRQb3MpID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCSAgICBzdGFydFBvcyA9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKCSAgICBuICs9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CgkgIH0KCX0gZWxzZSBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcFNvdXJjZSwgbFN0YXJ0KSA9PSBOVUxMKQoJICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCglUaGlzLT5iRGVjb21wcmVzcyAgICAgID0gVFJVRTsKCVRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgPSAwOwogICAgICB9CiAgICB9IGVsc2UgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBTb3VyY2UsIGxTdGFydCkgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7IC8qIENhbid0IGNvbnZlcnQgc291cmNlIHRvIG93biBmb3JtYXQgKi8KICB9IC8qIEZJWE1FOiBzb21ldGhpbmcgc3BlY2lhbCBmb3IgdGhlIG90aGVyIGZvcm1hdHM/ICovCgogIC8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGVub3VnaCBtZW1vcnkgZm9yIHBhcnRzICovCiAgaWYgKHBFZGl0ICE9IE5VTEwpIHsKICAgIERXT1JEIG5MYXN0U3RyZWFtOwoKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCArIGxMZW5ndGgsICZwU3RyZWFtLAoJCQkgICAgICAmZW5kUG9zLCAmbkxhc3RTdHJlYW0sIFRSVUUpOwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChuTGFzdFN0cmVhbSA9PSBzdHJlYW1OcikKICAgICAgbkxhc3RTdHJlYW0rKzsKCiAgICBuU3RyZWFtcyA9IG5MYXN0U3RyZWFtIC0gc3RyZWFtTnI7CiAgfSBlbHNlIAogICAgblN0cmVhbXMgPSAxOwogIGlmIChUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMSA+IFRoaXMtPm5UYWJsZVNpemUpIHsKICAgIG4gPSBUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMzM7CgogICAgVGhpcy0+cFN0cmVhbXMgPQogICAgICBHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPnBTdHJlYW1zLCBuICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSksIEdNRU1fU0hBUkV8R0hORCk7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5uVGFibGVTaXplID0gbjsKICB9CgogIGlmIChwbExlbmd0aCAhPSBOVUxMKQogICAgKnBsTGVuZ3RoID0gbExlbmd0aDsKCiAgLyogbm93IGRvIHRoZSByZWFsIHdvcmsgKi8KICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID4gKnBsU3RhcnQpIHsKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgKnBsU3RhcnQsICZwU3RyZWFtLAoJCQkgICAgICAmc3RhcnRQb3MsICZzdHJlYW1OciwgRkFMU0UpOwogICAgaWYgKHN0YXJ0UG9zICE9IFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0KSB7CiAgICAgIC8qIHNwbGl0IHN0cmVhbSBzdHJlYW1OciBhdCBzdGFydFBvcyAqLwogICAgICBtZW1tb3ZlKFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIgKyBuU3RyZWFtcyArIDEsCgkgICAgICBUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yLAoJICAgICAgKFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgLSBzdHJlYW1OciArIDEpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwoKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAyXS5kd0xlbmd0aCA9CglFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yICsgMikgLSBzdGFydFBvczsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAyXS5kd1N0YXJ0ID0gc3RhcnRQb3M7CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCA9CglzdGFydFBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0ucFN0cmVhbSk7CiAgICAgIHN0cmVhbU5yKys7CiAgICB9IGVsc2UgewogICAgICAvKiBpbnNlcnQgYmVmb3JlIHN0cmVhbSBhdCBzdHJlYW1OciAqLwogICAgICBtZW1tb3ZlKFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIgKyBuU3RyZWFtcywgVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciwKCSAgICAgIChUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zIC0gc3RyZWFtTnIpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgfQogIH0gZWxzZSAvKiBhcHBlbmQgdGhlIHN0cmVhbXMgKi8KICAgIHN0cmVhbU5yID0gVGhpcy0+blN0cmVhbXM7CgogIGlmIChwRWRpdCAhPSBOVUxMKSB7CiAgICAvKiBpbnNlcnQgdGhlIHBhcnRzIG9mIHRoZSBlZGl0YWJsZSBzdHJlYW0gaW5zdGVhZCBvZiBpdHNlbGYgKi8KICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCArIGxMZW5ndGgsICZwU3RyZWFtLAoJCQkgICAgICAmZW5kUG9zLCBOVUxMLCBGQUxTRSk7CiAgICBBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKHBFZGl0LCBsU3RhcnQsICZwU3RyZWFtLCAmc3RhcnRQb3MsICZuLCBGQUxTRSk7CgogICAgbWVtY3B5KFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsIHBFZGl0LT5wU3RyZWFtcyArIG4sCgkgICBuU3RyZWFtcyAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydCA8IHN0YXJ0UG9zKSB7CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCA9CglFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIHN0YXJ0UG9zOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydCAgPSBzdGFydFBvczsKICAgIH0KICAgIGlmIChlbmRQb3MgPCBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yICsgblN0cmVhbXMpKQogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIG5TdHJlYW1zXS5kd0xlbmd0aCA9CgllbmRQb3MgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIG5TdHJlYW1zXS5kd1N0YXJ0OwogIH0gZWxzZSB7CiAgICAvKiBhIHNpbXBsZSBzdHJlYW0gKi8KICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5wU3RyZWFtICA9IHBTb3VyY2U7CiAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydCAgPSBsU3RhcnQ7CiAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPSBsTGVuZ3RoOwogIH0KCiAgZm9yIChuID0gMDsgbiA8IG5TdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgbl0ucFN0cmVhbSk7CiAgICBpZiAoMCA8IHN0cmVhbU5yICsgbiAmJgoJVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyBuIC0gMV0ucFN0cmVhbSAhPSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIG5dLnBTdHJlYW0pIHsKICAgICAgVGhpcy0+c0luZm8uZHdGbGFncyB8PSBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVM7CiAgICAgIFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQrKzsKICAgIH0KICB9CiAgVGhpcy0+c0luZm8uZHdFZGl0Q291bnQrKzsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCArPSBsTGVuZ3RoOwogIFRoaXMtPm5TdHJlYW1zICs9IG5TdHJlYW1zOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DbG9uZShJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFWSVNUUkVBTSpwcFJlc3VsdCkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBJQVZJRWRpdFN0cmVhbUltcGwqIHBFZGl0OwogIERXT1JEIGk7CgogIFRSQUNFKCIoJXAsJXApXG4iLGlmYWNlLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogICpwcFJlc3VsdCA9IE5VTEw7CgogIHBFZGl0ID0gKElBVklFZGl0U3RyZWFtSW1wbCopQVZJRklMRV9DcmVhdGVFZGl0U3RyZWFtKE5VTEwpOwogIGlmIChwRWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgaWYgKFRoaXMtPm5TdHJlYW1zID4gcEVkaXQtPm5UYWJsZVNpemUpIHsKICAgIHBFZGl0LT5wU3RyZWFtcyA9IEdsb2JhbFJlQWxsb2NQdHIocEVkaXQtPnBTdHJlYW1zLCBUaGlzLT5uU3RyZWFtcyAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpLEdNRU1fU0hBUkV8R0hORCk7CiAgICBpZiAocEVkaXQtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgcEVkaXQtPm5UYWJsZVNpemUgPSBUaGlzLT5uU3RyZWFtczsKICB9CiAgcEVkaXQtPm5TdHJlYW1zID0gVGhpcy0+blN0cmVhbXM7CiAgbWVtY3B5KHBFZGl0LT5wU3RyZWFtcywgVGhpcy0+cFN0cmVhbXMsCiAgICAgICAgIFRoaXMtPm5TdHJlYW1zICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogIG1lbWNweSgmcEVkaXQtPnNJbmZvLCZUaGlzLT5zSW5mbyxzaXplb2YoVGhpcy0+c0luZm8pKTsKICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+blN0cmVhbXM7IGkrKykgewogICAgaWYgKHBFZGl0LT5wU3RyZWFtc1tpXS5wU3RyZWFtICE9IE5VTEwpCiAgICAgIElBVklTdHJlYW1fQWRkUmVmKHBFZGl0LT5wU3RyZWFtc1tpXS5wU3RyZWFtKTsKICB9CgogICpwcFJlc3VsdCA9IChQQVZJU1RSRUFNKSZwRWRpdC0+aUFWSVN0cmVhbTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuU2V0SW5mbyhJQVZJRWRpdFN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSxMT05HIHNpemUpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhc2ksc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplICE9IHNpemVvZihBVklTVFJFQU1JTkZPVykpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CiAgaWYgKGFzaS0+ZHdTY2FsZSA9PSAwIHx8IGFzaS0+ZHdSYXRlID09IDAgfHwgKExPTkcpYXNpLT5kd1F1YWxpdHkgPCAtMSB8fAogICAgICBhc2ktPmR3UXVhbGl0eSA+IElDUVVBTElUWV9ISUdIKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgVGhpcy0+c0luZm8ud0xhbmd1YWdlID0gYXNpLT53TGFuZ3VhZ2U7CiAgVGhpcy0+c0luZm8ud1ByaW9yaXR5ID0gYXNpLT53UHJpb3JpdHk7CiAgVGhpcy0+c0luZm8uZHdTdGFydCAgID0gYXNpLT5kd1N0YXJ0OwogIGlmIChhc2ktPmR3UmF0ZSAhPSAwKQogICAgVGhpcy0+c0luZm8uZHdSYXRlICA9IGFzaS0+ZHdSYXRlOwogIGlmIChhc2ktPmR3U2NhbGUgIT0gMCkKICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUgPSBhc2ktPmR3U2NhbGU7CiAgaWYgKGFzaS0+ZHdRdWFsaXR5IDw9IElDUVVBTElUWV9ISUdIKQogICAgVGhpcy0+c0luZm8uZHdRdWFsaXR5ID0gSUNRVUFMSVRZX0hJR0g7CiAgQ29weVJlY3QoJlRoaXMtPnNJbmZvLnJjRnJhbWUsICZhc2ktPnJjRnJhbWUpOwogIG1lbWNweSgmVGhpcy0+c0luZm8uc3pOYW1lLCAmYXNpLT5zek5hbWUsIHNpemVvZihhc2ktPnN6TmFtZSkpOwogIFRoaXMtPnNJbmZvLmR3RWRpdENvdW50Kys7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaikKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlLHJlZmlpZCxvYmopOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSkKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX0FkZFJlZigoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSk7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSppZmFjZSkKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1JlbGVhc2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFlOwoKICBpZiAobFBhcmFtMiAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpIHsKICAgIFRoaXMtPnBTdHJlYW1zID0KICAgICAgR2xvYmFsQWxsb2NQdHIoR01FTV9TSEFSRXxHSE5ELCAyNTYgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5uVGFibGVTaXplID0gMjU2OwogIH0KCiAgaWYgKGxQYXJhbTEgIT0gMCkgewogICAgSUFWSVN0cmVhbV9JbmZvKChQQVZJU1RSRUFNKWxQYXJhbTEsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgICBJQVZJU3RyZWFtX0FkZFJlZigoUEFWSVNUUkVBTSlsUGFyYW0xKTsKICAgIFRoaXMtPnBTdHJlYW1zWzBdLnBTdHJlYW0gID0gKFBBVklTVFJFQU0pbFBhcmFtMTsKICAgIFRoaXMtPnBTdHJlYW1zWzBdLmR3U3RhcnQgID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIFRoaXMtPnBTdHJlYW1zWzBdLmR3TGVuZ3RoID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgICBUaGlzLT5uU3RyZWFtcyA9IDE7CiAgfQogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSkKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLGlmYWNlLHBzaSxzaXplKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgaWYgKHBzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGlmIChUaGlzLT5wYWUtPmJEZWNvbXByZXNzKQogICAgVGhpcy0+cGFlLT5zSW5mby5mY2NIYW5kbGVyID0gMDsKCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnBhZS0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnBhZS0+c0luZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5wYWUtPnNJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIExPTkcgICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgZmxhZ3MpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgUEFWSVNUUkVBTSBzdHJlYW07CiAgRFdPUkQgICAgICBzdHJlYW1Qb3MsIHN0cmVhbU5yOwoKICBUUkFDRSgiKCVwLCVsZCwweCUwOGxYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpCiAgICBwb3MgPSAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0OwoKICAvKiBvdXRzaWRlIG9mIHN0cmVhbT8gKi8KICBpZiAocG9zIDwgKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCB8fAogICAgICAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0ICsgKExPTkcpVGhpcy0+c0luZm8uZHdMZW5ndGggPD0gcG9zKQogICAgcmV0dXJuIC0xOwoKICAvKiBtYXAgb3VyIHBvc2l0aW9uIHRvIGEgc3RyZWFtIGFuZCBwb3NpdGlvbiBpbiBpdCAqLwogIGlmIChBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKFRoaXMsIHBvcywgJnN0cmVhbSwgJnN0cmVhbVBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtTnIsIFRSVUUpKQogICAgcmV0dXJuIC0xOyAvKiBkb2Vzbid0IGV4aXN0ICovCgogIGlmIChUaGlzLT5iRGVjb21wcmVzcykgewogICAgLyogb25seSBvbmUgc3RyZWFtIC0tIGZvcm1hdCBjaGFuZ2VzIG9ubHkgYXQgc3RhcnQgKi8KICAgIGlmIChmbGFncyAmIEZJTkRfRk9STUFUKQogICAgICByZXR1cm4gKGZsYWdzICYgRklORF9ORVhUID8gLTEgOiAwKTsKCiAgICAvKiBGSVhNRTogbWFwIHBvc2l0aW9ucyBiYWNrIHRvIHVzICovCiAgICByZXR1cm4gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKHN0cmVhbSwgc3RyZWFtUG9zLCBmbGFncyk7CiAgfSBlbHNlIHsKICAgIC8qIGFzc3VtZSBjaGFuZ2Ugb2YgZm9ybWF0IGV2ZXJ5IGZyYW1lICovCiAgICByZXR1cm4gcG9zOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBmb3JtYXQsTE9ORypmbXRzaXplKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqIGNvbnN0KWlmYWNlKS0+cGFlOwogIExQQklUTUFQSU5GT0hFQURFUiAgbHA7CiAgUEFWSVNUUkVBTSAgICAgICAgICBzdHJlYW07CiAgRFdPUkQgICAgICAgICAgICAgICBuOwogIEhSRVNVTFQgICAgICAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVwKVxuIixpZmFjZSxwb3MsZm9ybWF0LGZtdHNpemUpOwoKICBpZiAoZm10c2l6ZSA9PSBOVUxMIHx8IHBvcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQgfHwKICAgICAgVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDw9IHBvcykKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIGZpbmQgc3RyZWFtIGNvcnJlc3BvbmRpbmcgdG8gcG9zaXRpb24gKi8KICBociA9IEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgcG9zLCAmc3RyZWFtLCAmbiwgTlVMTCwgRkFMU0UpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBpZiAoISBUaGlzLT5iRGVjb21wcmVzcykKICAgIHJldHVybiBJQVZJU3RyZWFtX1JlYWRGb3JtYXQoc3RyZWFtLCBuLCBmb3JtYXQsIGZtdHNpemUpOwoKICBscCA9IChMUEJJVE1BUElORk9IRUFERVIpQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgc3RyZWFtLCBuKTsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgaWYgKGxwLT5iaUJpdENvdW50IDw9IDgpIHsKICAgIG4gID0gKGxwLT5iaUNsclVzZWQgPiAwID8gbHAtPmJpQ2xyVXNlZCA6IDEgPDwgbHAtPmJpQml0Q291bnQpOwogICAgbiAqPSBzaXplb2YoUkdCUVVBRCk7CiAgfSBlbHNlCiAgICBuID0gMDsKICBuICs9IGxwLT5iaVNpemU7CiAgCiAgbWVtY3B5KGZvcm1hdCwgbHAsIG1pbigoTE9ORyluLCAqZm10c2l6ZSkpOwogIGhyID0gKChMT05HKW4gPiAqZm10c2l6ZSA/IEFWSUVSUl9CVUZGRVJUT09TTUFMTCA6IEFWSUVSUl9PSyk7CiAgKmZtdHNpemUgPSBuOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLGlmYWNlLHBvcyxmb3JtYXQsZm9ybWF0c2l6ZSk7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgYnVmZmVyc2l6ZSxMT05HKmJ5dGVzcmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXBsZXNyZWFkKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqIGNvbnN0KWlmYWNlKS0+cGFlOwogIFBBVklTVFJFQU0gc3RyZWFtOwogIERXT1JEICAgc3RyZWFtUG9zLCBzdHJlYW1OcjsKICBMT05HICAgIHJlYWRCeXRlcywgcmVhZFNhbXBsZXMsIGNvdW50OwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsJXAsJXApIC0tIDB4JTA4bFhcbiIsaWZhY2Usc3RhcnQsc2FtcGxlcywKICAgICAgICBidWZmZXIsYnVmZmVyc2l6ZSxieXRlc3JlYWQsc2FtcGxlc3JlYWQsVGhpcy0+c0luZm8uZmNjVHlwZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gMDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IDA7CiAgaWYgKGJ1ZmZlcnNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwogIGlmICgoRFdPUkQpc3RhcnQgPCBUaGlzLT5zSW5mby5kd1N0YXJ0IHx8CiAgICAgIFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8IChEV09SRClzdGFydCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAvKiBhdWRpbyBsaWtlIGRhdGEgLS0gc2FtcGxlLWJhc2VkICovCiAgICBkbyB7CiAgICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgICAgcmV0dXJuIEFWSUVSUl9PSzsgLyogbm90aGluZyBhdCBhbGwgb3IgYWxyZWFkeSBkb25lICovCgogICAgICBpZiAoRkFJTEVEKEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgc3RhcnQsICZzdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtUG9zLCAmc3RyZWFtTnIsIEZBTFNFKSkpCiAgICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgICAgIC8qIGxpbWl0IHRvIGVuZCBvZiB0aGUgc3RyZWFtICovCiAgICAgIGNvdW50ID0gc2FtcGxlczsKICAgICAgaWYgKHN0cmVhbVBvcyArIGNvdW50ID4gRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikpCiAgICAgICAgY291bnQgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIHN0cmVhbVBvczsKCiAgICAgIGhyID0gSUFWSVN0cmVhbV9SZWFkKHN0cmVhbSwgc3RyZWFtUG9zLCBjb3VudCwgYnVmZmVyLCBidWZmZXJzaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVhZEJ5dGVzLCAmcmVhZFNhbXBsZXMpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgICByZXR1cm4gaHI7CiAgICAgIGlmIChyZWFkQnl0ZXMgPT0gMCAmJiByZWFkU2FtcGxlcyA9PSAwICYmIGNvdW50ICE9IDApCiAgICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsgLyogZm9yIGJhZCBzdHJlYW0gaW1wbGVtZW50YXRpb25zICovCgogICAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgICAqc2FtcGxlc3JlYWQgKz0gcmVhZFNhbXBsZXM7CiAgICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgICAqYnl0ZXNyZWFkICs9IHJlYWRCeXRlczsKICAgICAgaWYgKGJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgYnVmZmVyID0gKChMUEJZVEUpYnVmZmVyKStyZWFkQnl0ZXM7CiAgICAgICAgYnVmZmVyc2l6ZSAgICAgLT0gcmVhZEJ5dGVzOwogICAgICB9CiAgICAgIHN0YXJ0ICAgKz0gY291bnQ7CiAgICAgIHNhbXBsZXMgLT0gY291bnQ7CiAgICB9IHdoaWxlIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPiBzdGFydCk7CiAgfSBlbHNlIHsKICAgIC8qIHZpZGVvIGxpa2UgZGF0YSAtLSBmcmFtZS1iYXNlZCAqLwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwOwoKICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CgogICAgaWYgKEZBSUxFRChBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKFRoaXMsIHN0YXJ0LCAmc3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdHJlYW1Qb3MsICZzdHJlYW1OciwgRkFMU0UpKSkKICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgICBscCA9IEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHN0cmVhbSwgc3RyZWFtUG9zKTsKICAgIGlmIChscCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICAgIGlmIChidWZmZXIgIT0gTlVMTCkgewogICAgICAvKiBuZWVkIHNpemUgb2YgZm9ybWF0IHRvIHNraXAgKi8KICAgICAgaWYgKGxwLT5iaUJpdENvdW50IDw9IDgpIHsKICAgICAgICBjb3VudCAgPSBscC0+YmlDbHJVc2VkID4gMCA/IGxwLT5iaUNsclVzZWQgOiAxIDw8IGxwLT5iaUJpdENvdW50OwogICAgICAgIGNvdW50ICo9IHNpemVvZihSR0JRVUFEKTsKICAgICAgfSBlbHNlCiAgICAgICAgY291bnQgPSAwOwogICAgICBjb3VudCArPSBscC0+YmlTaXplOwoKICAgICAgaWYgKGJ1ZmZlcnNpemUgPCBscC0+YmlTaXplSW1hZ2UpCiAgICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICAgICAgbWVtY3B5KGJ1ZmZlciwgKExQQllURSlscCArIGNvdW50LCBscC0+YmlTaXplSW1hZ2UpOwogICAgfQoKICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IGxwLT5iaVNpemVJbWFnZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSAxOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXB3cml0dGVuLExPTkcqYnl0ZXN3cml0dGVuKQp7CiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwweCUwOGxYLCVwLCVwKVxuIixpZmFjZSxzdGFydCxzYW1wbGVzLGJ1ZmZlciwKICAgICAgICBidWZmZXJzaXplLGZsYWdzLHNhbXB3cml0dGVuLGJ5dGVzd3JpdHRlbik7CgogIC8qIGJlIHN1cmUgcmV0dXJuIHBhcmFtZXRlcnMgaGF2ZSBjb3JyZWN0IHZhbHVlcyAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcykKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkKVxuIixpZmFjZSxzdGFydCxzYW1wbGVzKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX0N1dCgoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSwmc3RhcnQsJnNhbXBsZXMsTlVMTCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgbHAsTE9ORyAqbHByZWFkKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqIGNvbnN0KWlmYWNlKS0+cGFlOwogIERXT1JEIG47CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsaWZhY2UsZmNjLGxwLGxwcmVhZCk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHAgPT0gTlVMTCB8fCBscHJlYWQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIHNpbXBseSBhc2sgZXZlcnkgc3RyZWFtIGFuZCByZXR1cm4gdGhlIGZpcnN0IGJsb2NrIGZvdW5kICovCiAgZm9yIChuID0gMDsgbiA8IFRoaXMtPm5TdHJlYW1zOyBuKyspIHsKICAgIEhSRVNVTFQgaHIgPSBJQVZJU3RyZWFtX1JlYWREYXRhKFRoaXMtPnBTdHJlYW1zW25dLnBTdHJlYW0sZmNjLGxwLGxwcmVhZCk7CgogICAgaWYgKFNVQ0NFRURFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogICpscHJlYWQgPSAwOwogIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgbHAsTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVsZClcbiIsaWZhY2UsZmNjLGxwLHNpemUpOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGxlbikKewogIElFZGl0QVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJRWRpdEFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLGlmYWNlLGluZm8sbGVuKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1NldEluZm8oKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUsaW5mbyxsZW4pOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblF1ZXJ5SW50ZXJmYWNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKQp7CiAgSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKlRoaXMgPSAoSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlLCByZWZpaWQsIG9iaik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuQWRkUmVmKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UpCnsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqVGhpcyA9IChJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fQWRkUmVmKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UpCnsKICBJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqVGhpcyA9IChJRWRpdFN0cmVhbUludGVybmFsSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUmVsZWFzZSgoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSk7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsTFBWT0lEKnBwaW1wbCkKewogIElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICpUaGlzID0gKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXApIC0+ICVwXG4iLCBpZmFjZSwgcHBpbXBsLCBUaGlzLT5wYWUpOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwogIGFzc2VydChwcGltcGwgIT0gTlVMTCk7CgogICpwcGltcGwgPSBUaGlzLT5wYWU7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQo=