LyoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBpbnRlcm5hbCBpbnRlcmZhY2UgdG8gZ2V0IGFjY2VzcyB0byB0YWJsZSBvZiBzdHJlYW0gaW4gYW4gZWRpdGFibGUgc3RyZWFtICovCnR5cGVkZWYgc3RydWN0IElFZGl0U3RyZWFtSW50ZXJuYWwgSUVkaXRTdHJlYW1JbnRlcm5hbDsKCnR5cGVkZWYgc3RydWN0IF9FZGl0U3RyZWFtVGFibGUgewogIFBBVklTVFJFQU0gcFN0cmVhbTsgIC8qIHN0cmVhbSB3aGljaCBjb250YWlucyB0aGUgZGF0YSAqLwogIERXT1JEICAgICAgZHdTdGFydDsgIC8qIHdoZXJlIHN0YXJ0cyB0aGUgcGFydCB3aGljaCBpcyBhbHNvIG91ciAqLwogIERXT1JEICAgICAgZHdMZW5ndGg7IC8qIGhvdyBtYW55IGlzIGFsc28gaW4gdGhpcyBzdHJlYW0gKi8KfSBFZGl0U3RyZWFtVGFibGU7CgojZGVmaW5lIElOVEVSRkFDRSBJRWRpdFN0cmVhbUludGVybmFsCiNkZWZpbmUgSUVkaXRTdHJlYW1JbnRlcm5hbF9NRVRIT0RTIFwKICAgIElVbmtub3duX01FVEhPRFMgXAogICAgU1RETUVUSE9EKEdldEVkaXRTdHJlYW1JbXBsKShUSElTXyBMUFZPSUQqKSBQVVJFOwpJQ09NX0RFRklORShJRWRpdFN0cmVhbUludGVybmFsLCBJVW5rbm93bikKI3VuZGVmIElOVEVSRkFDRQoKI2RlZmluZSBFZGl0U3RyZWFtRW5kKFRoaXMsc3RyZWFtTnIpICgoVGhpcyktPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICsgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzKS0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUVkaXRTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkFkZFJlZihJQVZJRWRpdFN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblJlbGVhc2UoSUFWSUVkaXRTdHJlYW0qaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DdXQoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ29weShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUGFzdGUoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0gcFNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBsU3RhcnQsTE9ORyBsRW5kKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ2xvbmUoSUFWSUVkaXRTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5TZXRJbmZvKElBVklFZGl0U3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpLExPTkcgc2l6ZSk7CgpzdHJ1Y3QgSUNPTV9WVEFCTEUoSUFWSUVkaXRTdHJlYW0pIGllZGl0c3RyZWFtID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSUFWSUVkaXRTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRWRpdFN0cmVhbV9mbkFkZFJlZiwKICBJQVZJRWRpdFN0cmVhbV9mblJlbGVhc2UsCiAgSUFWSUVkaXRTdHJlYW1fZm5DdXQsCiAgSUFWSUVkaXRTdHJlYW1fZm5Db3B5LAogIElBVklFZGl0U3RyZWFtX2ZuUGFzdGUsCiAgSUFWSUVkaXRTdHJlYW1fZm5DbG9uZSwKICBJQVZJRWRpdFN0cmVhbV9mblNldEluZm8KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORypmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGJ1ZmZlcnNpemUsTE9ORypieXRlc3JlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypzYW1wd3JpdHRlbixMT05HKmJ5dGVzd3JpdHRlbik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HICpscHJlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgbHAsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0cnVjdCBJQ09NX1ZUQUJMRShJQVZJU3RyZWFtKSBpZWRpdHN0YXN0ID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSUVkaXRBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZiwKICBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5JbmZvLAogIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJRWRpdEFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkLAogIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUVkaXRBVklTdHJlYW1fZm5EZWxldGUsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUXVlcnlJbnRlcmZhY2UoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZihJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkdldEVkaXRTdHJlYW1JbXBsKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsTFBWT0lEKnBwaW1wbCk7CgpzdHJ1Y3QgSUNPTV9WVEFCTEUoSUVkaXRTdHJlYW1JbnRlcm5hbCkgaWVkaXRzdHJlYW1pbnRlcm5hbCA9IHsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5RdWVyeUludGVyZmFjZSwKICBJRWRpdFN0cmVhbUludGVybmFsX2ZuQWRkUmVmLAogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlLAogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5HZXRFZGl0U3RyZWFtSW1wbAp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklFZGl0U3RyZWFtSW1wbCBJQVZJRWRpdFN0cmVhbUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUVkaXRBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElDT01fVkZJRUxEKElBVklTdHJlYW0pOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgSUFWSUVkaXRTdHJlYW1JbXBsICpwYWU7Cn0gSUVkaXRBVklTdHJlYW1JbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lFZGl0U3RyZWFtSW50ZXJuYWxJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElDT01fVkZJRUxEKElFZGl0U3RyZWFtSW50ZXJuYWwpOwoKICAvKiBJRWRpdFN0cmVhbUludGVybmFsIHN0dWZmICovCiAgSUFWSUVkaXRTdHJlYW1JbXBsICpwYWU7Cn0gSUVkaXRTdHJlYW1JbnRlcm5hbEltcGw7CgpzdHJ1Y3QgX0lBVklFZGl0U3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJQ09NX1ZGSUVMRChJQVZJRWRpdFN0cmVhbSk7CiAgRFdPUkQgIHJlZjsKCiAgLyogSUFWSUVkaXRTdHJlYW0gc3R1ZmYgKi8KICBJRWRpdEFWSVN0cmVhbUltcGwgICAgICBpQVZJU3RyZWFtOwogIElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsIGlFZGl0U3RyZWFtSW50ZXJuYWw7CgogIEFWSVNUUkVBTUlORk9XICAgICAgIHNJbmZvOwoKICBFZGl0U3RyZWFtVGFibGUgICAgICpwU3RyZWFtczsKICBEV09SRCAgICAgICAgICAgICAgICBuU3RyZWFtczsgICAvKiBjdXJyZW50IGZpbGwgbGV2ZWwgb2YgcFN0cmVhbXMgdGFibGUgKi8KICBEV09SRCAgICAgICAgICAgICAgICBuVGFibGVTaXplOyAvKiBzaXplIG9mIHBTdHJlYW1zIHRhYmxlICovCgogIEJPT0wgICAgICAgICAgICAgICAgIGJEZWNvbXByZXNzOwogIFBBVklTVFJFQU0gICAgICAgICAgIHBDdXJTdHJlYW07CiAgUEdFVEZSQU1FICAgICAgICAgICAgcGc7ICAgICAgICAgLyogSUdldEZyYW1lIGZvciBwQ3VyU3RyZWFtICovCiAgTFBCSVRNQVBJTkZPSEVBREVSICAgbHBGcmFtZTsgICAgLyogZnJhbWUgb2YgcEN1clN0cmVhbSAqLwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKUEFWSUVESVRTVFJFQU0gQVZJRklMRV9DcmVhdGVFZGl0U3RyZWFtKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqcGVkaXQgPSBOVUxMOwoKICBwZWRpdCA9IChJQVZJRWRpdFN0cmVhbUltcGwqKUxvY2FsQWxsb2MoTFBUUixzaXplb2YoSUFWSUVkaXRTdHJlYW1JbXBsKSk7CiAgaWYgKHBlZGl0ID09IE5VTEwpCiAgICByZXR1cm4gTlVMTDsKCiAgcGVkaXQtPmxwVnRibCAgICAgICAgICAgID0gJmllZGl0c3RyZWFtOwogIHBlZGl0LT5pQVZJU3RyZWFtLmxwVnRibCA9ICZpZWRpdHN0YXN0OwogIHBlZGl0LT5pQVZJU3RyZWFtLnBhZSAgICA9IHBlZGl0OwogIHBlZGl0LT5pRWRpdFN0cmVhbUludGVybmFsLmxwVnRibCA9ICZpZWRpdHN0cmVhbWludGVybmFsOwogIHBlZGl0LT5pRWRpdFN0cmVhbUludGVybmFsLnBhZSAgICA9IHBlZGl0OwogIHBlZGl0LT5yZWYgPSAxOwoKICBJQVZJU3RyZWFtX0NyZWF0ZSgoUEFWSVNUUkVBTSkmcGVkaXQtPmlBVklTdHJlYW0sKExQQVJBTSlwc3RyZWFtLDApOwoKICByZXR1cm4gKFBBVklFRElUU1RSRUFNKXBlZGl0Owp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcywKCQkJCQkgRFdPUkQgcG9zLFBBVklTVFJFQU0gKnBwU3RyZWFtLAoJCQkJCSBEV09SRCogc3RyZWFtUG9zLAoJCQkJCSBEV09SRCogc3RyZWFtTnIsQk9PTCBiRmluZFNhbXBsZSkKewogIERXT1JEIG47CgogIFRSQUNFKCIoJXAsJWx1LCVwLCVwLCVwLCVkKVxuIixUaGlzLHBvcyxwcFN0cmVhbSxzdHJlYW1Qb3MsCiAgICAgICAgc3RyZWFtTnIsYkZpbmRTYW1wbGUpOwoKICBpZiAocG9zIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIHBvcyAtPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5uU3RyZWFtczsgbisrKSB7CiAgICBpZiAocG9zIDwgVGhpcy0+cFN0cmVhbXNbbl0uZHdMZW5ndGgpIHsKICAgICAgKnBwU3RyZWFtICA9IFRoaXMtPnBTdHJlYW1zW25dLnBTdHJlYW07CiAgICAgICpzdHJlYW1Qb3MgPSBUaGlzLT5wU3RyZWFtc1tuXS5kd1N0YXJ0ICsgcG9zOwogICAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgICAqc3RyZWFtTnIgPSBuOwoKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0KICAgIHBvcyAtPSBUaGlzLT5wU3RyZWFtc1tuXS5kd0xlbmd0aDsKICB9CiAgaWYgKHBvcyA9PSAwICYmIGJGaW5kU2FtcGxlKSB7CiAgICAqcHBTdHJlYW0gID0gVGhpcy0+cFN0cmVhbXNbLS1uXS5wU3RyZWFtOwogICAgKnN0cmVhbVBvcyA9IEVkaXRTdHJlYW1FbmQoVGhpcywgbik7CiAgICBpZiAoc3RyZWFtTnIgIT0gTlVMTCkKICAgICAgKnN0cmVhbU5yID0gbjsKCiAgICBUUkFDRSgiIC0tIHBvcz0wICYmIGI9MSAtPiAoJXAsJWx1LCVsdSlcbiIsKnBwU3RyZWFtLCAqc3RyZWFtUG9zLCBuKTsKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlIHsKICAgICpwcFN0cmVhbSA9IE5VTEw7CiAgICAqc3RyZWFtUG9zID0gMDsKICAgIGlmIChzdHJlYW1OciAhPSBOVUxMKQogICAgICAqc3RyZWFtTnIgPSAwOwoKICAgIFRSQUNFKCIgLT4gRVJST1IgKE5VTEwsMCwwKVxuIik7CiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIH0KfQoKc3RhdGljIExQVk9JRCBBVklGSUxFX1JlYWRGcmFtZShJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcykKewogIFBHRVRGUkFNRSBwZzsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLFRoaXMscHN0cmVhbSxwb3MpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIC8qIGlmIHN0cmVhbSBjaGFuZ2VzIG1ha2Ugc3VyZSB0aGF0IG9ubHkgcGFsZXR0ZSBjaGFuZ2VzICovCiAgaWYgKFRoaXMtPnBDdXJTdHJlYW0gIT0gcHN0cmVhbSkgewogICAgcGcgPSBBVklTdHJlYW1HZXRGcmFtZU9wZW4ocHN0cmVhbSwgTlVMTCk7CiAgICBpZiAocGcgPT0gTlVMTCkKICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAoVGhpcy0+cGcgIT0gTlVMTCkgewogICAgICBpZiAoSUdldEZyYW1lX1NldEZvcm1hdChwZywgVGhpcy0+bHBGcmFtZSwgTlVMTCwgMCwgMCwgLTEsIC0xKSkgewogICAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UocGcpOwogICAgICAgIEVSUigiOiBJR2V0RnJhbWVfU2V0Rm9ybWF0IGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgIH0KICAgICAgQVZJU3RyZWFtR2V0RnJhbWVDbG9zZShUaGlzLT5wZyk7CiAgICB9CiAgICBUaGlzLT5wZyAgICAgICAgID0gcGc7CiAgICBUaGlzLT5wQ3VyU3RyZWFtID0gcHN0cmVhbTsKICB9CgogIC8qIG5vdyBnZXQgdGhlIGRlY29tcHJlc3NlZCBmcmFtZSAqLwogIFRoaXMtPmxwRnJhbWUgPSBBVklTdHJlYW1HZXRGcmFtZShUaGlzLT5wZywgcG9zKTsKICBpZiAoVGhpcy0+bHBGcmFtZSAhPSBOVUxMKQogICAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+bHBGcmFtZS0+YmlTaXplSW1hZ2U7CgogIHJldHVybiBUaGlzLT5scEZyYW1lOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1JlbW92ZVN0cmVhbShJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMsIERXT1JEIG5yKQp7CiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KG5yIDwgVGhpcy0+blN0cmVhbXMpOwoKICAvKiByZW1vdmUgcGFydCBuciAqLwogIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtc1tucl0ucFN0cmVhbSk7CiAgVGhpcy0+blN0cmVhbXMtLTsKICBpZiAoVGhpcy0+blN0cmVhbXMgLSBuciA+IDApIHsKICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBuciwgVGhpcy0+cFN0cmVhbXMgKyBuciArIDEsCiAgICAgICAgICAgIChUaGlzLT5uU3RyZWFtcyAtIG5yKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICB9CiAgVGhpcy0+cFN0cmVhbXNbVGhpcy0+blN0cmVhbXNdLnBTdHJlYW0gID0gTlVMTDsKICBUaGlzLT5wU3RyZWFtc1tUaGlzLT5uU3RyZWFtc10uZHdTdGFydCAgPSAwOwogIFRoaXMtPnBTdHJlYW1zW1RoaXMtPm5TdHJlYW1zXS5kd0xlbmd0aCA9IDA7CgogIC8qIHRyeSB0byBtZXJnZSB0aGUgcGFydCBiZWZvcmUgdGhlIGRlbGV0ZWQgb25lIGFuZCB0aGUgb25lIGFmdGVyIGl0ICovCiAgaWYgKDAgPCBuciAmJiAwIDwgVGhpcy0+blN0cmVhbXMgJiYKICAgICAgVGhpcy0+cFN0cmVhbXNbbnIgLSAxXS5wU3RyZWFtID09IFRoaXMtPnBTdHJlYW1zW25yXS5wU3RyZWFtKSB7CiAgICBpZiAoRWRpdFN0cmVhbUVuZChUaGlzLCBuciAtIDEpID09IFRoaXMtPnBTdHJlYW1zW25yXS5kd1N0YXJ0KSB7CiAgICAgIFRoaXMtPnBTdHJlYW1zW25yIC0gMV0uZHdMZW5ndGggKz0gVGhpcy0+cFN0cmVhbXNbbnJdLmR3TGVuZ3RoOwogICAgICByZXR1cm4gQVZJRklMRV9SZW1vdmVTdHJlYW0oVGhpcywgbnIpOwogICAgfQogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEJPT0wgQVZJRklMRV9Gb3JtYXRzRXF1YWwoUEFWSVNUUkVBTSBhdmkxLCBQQVZJU1RSRUFNIGF2aTIpCnsKICBMUFZPSUQgZm10MSA9IE5VTEwsIGZtdDIgPSBOVUxMOwogIExPTkcgc2l6ZTEsIHNpemUyLCBzdGFydDEsIHN0YXJ0MjsKICBCT09MIHN0YXR1cyA9IEZBTFNFOwoKICBhc3NlcnQoYXZpMSAhPSBOVUxMICYmIGF2aTIgIT0gTlVMTCk7CgogIC8qIGdldCBzdHJlYW0gc3RhcnRzIGFuZCBjaGVjayBmb3JtYXQgc2l6ZXMgKi8KICBzdGFydDEgPSBBVklTdHJlYW1TdGFydChhdmkxKTsKICBzdGFydDIgPSBBVklTdHJlYW1TdGFydChhdmkyKTsKICBpZiAoRkFJTEVEKEFWSVN0cmVhbUZvcm1hdFNpemUoYXZpMSwgc3RhcnQxLCAmc2l6ZTEpKSkKICAgIHJldHVybiBGQUxTRTsKICBpZiAoRkFJTEVEKEFWSVN0cmVhbUZvcm1hdFNpemUoYXZpMiwgc3RhcnQyLCAmc2l6ZTIpKSkKICAgIHJldHVybiBGQUxTRTsKICBpZiAoc2l6ZTEgIT0gc2l6ZTIpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIHNpemVzIG1hdGNoLCBub3cgZ2V0IGZvcm1hdHMgYW5kIGNvbXBhcmUgdGhlbSAqLwogIGZtdDEgPSBHbG9iYWxBbGxvY1B0cihHSE5ELCBzaXplMSk7CiAgaWYgKGZtdDEgPT0gTlVMTCkKICAgIHJldHVybiBGQUxTRTsKICBpZiAoU1VDQ0VFREVEKEFWSVN0cmVhbVJlYWRGb3JtYXQoYXZpMSwgc3RhcnQxLCBmbXQxLCAmc2l6ZTEpKSkgewogICAgZm10MiA9IEdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemUxKTsKICAgIGlmIChmbXQyICE9IE5VTEwpIHsKICAgICAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KGF2aTIsIHN0YXJ0MiwgZm10MiwgJnNpemUxKSkpCiAgICAgICAgc3RhdHVzID0gKG1lbWNtcChmbXQxLCBmbXQyLCBzaXplMSkgPT0gMCk7CiAgICB9CiAgfQoKICBpZiAoZm10MiAhPSBOVUxMKQogICAgR2xvYmFsRnJlZVB0cihmbXQyKTsKICBHbG9iYWxGcmVlUHRyKGZtdDEpOwoKICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJRWRpdFN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKQp7CiAgSUNPTV9USElTKElBVklFZGl0U3RyZWFtSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSUVkaXRTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSBpZmFjZTsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUFWSVN0cmVhbTsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lFZGl0U3RyZWFtSW50ZXJuYWwsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUVkaXRTdHJlYW1JbnRlcm5hbDsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkFkZFJlZihJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElDT01fVEhJUyhJQVZJRWRpdFN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgKyAxKTsKICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElDT01fVEhJUyhJQVZJRWRpdFN0cmVhbUltcGwsaWZhY2UpOwogIERXT1JEIGk7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIFRoaXMtPnJlZiAtIDEpOwoKICBpZiAoIS0tKFRoaXMtPnJlZikpIHsKICAgIC8qIHJlbGVhYXNlIG1lbW9yeSAqLwogICAgaWYgKFRoaXMtPnBnICE9IE5VTEwpCiAgICAgIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoVGhpcy0+cGcpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zICE9IE5VTEwpIHsKICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPm5TdHJlYW1zOyBpKyspIHsKICAgICAgICBpZiAoVGhpcy0+cFN0cmVhbXNbaV0ucFN0cmVhbSAhPSBOVUxMKQogICAgICAgICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW1zW2ldLnBTdHJlYW0pOwogICAgICB9CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+cFN0cmVhbXMpOwogICAgfQoKICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkN1dChJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpCnsKICBJQ09NX1RISVMoSUFWSUVkaXRTdHJlYW1JbXBsLGlmYWNlKTsKICBQQVZJU1RSRUFNIHN0cmVhbTsKICBEV09SRCAgICAgIHN0YXJ0LCBsZW4sIHN0cmVhbVBvcywgc3RyZWFtTnI7CiAgSFJFU1VMVCAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsaWZhY2UscGxTdGFydCxwbExlbmd0aCxwcFJlc3VsdCk7CgogIGlmIChwcFJlc3VsdCAhPSBOVUxMKQogICAgKnBwUmVzdWx0ID0gTlVMTDsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8IHBsTGVuZ3RoID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogaWYgYXNrZWQgZm9yIGN1dHRlZCBwYXJ0IGNvcHkgaXQgYmVmb3JlIGRlbGV0aW5nICovCiAgaWYgKHBwUmVzdWx0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ29weShpZmFjZSwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICBzdGFydCA9ICpwbFN0YXJ0OwogIGxlbiAgID0gKnBsTGVuZ3RoOwoKICAvKiBub3cgZGVsZXRlIHRoZSByZXF1ZXN0ZWQgcGFydCAqLwogIHdoaWxlIChsZW4gPiAwKSB7CiAgICBociA9IEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgc3RhcnQsICZzdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0cmVhbVBvcywgJnN0cmVhbU5yLCBGQUxTRSk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ID09IHN0cmVhbVBvcykgewogICAgICAvKiBkZWxldGluZyBmcm9tIHN0YXJ0IG9mIHBhcnQgKi8KICAgICAgaWYgKGxlbiA8IFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCkgewogICAgICAgIHN0YXJ0ICs9IGxlbjsKICAgICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydCAgKz0gbGVuOwogICAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCAtPSBsZW47CiAgICAgICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gbGVuOwogICAgICAgIGxlbiA9IDA7CgogICAgICAgIC8qIHdlIG11c3QgcmV0dXJuIGRlY29tcHJlc3NlZCBkYXRhIG5vdyAqLwogICAgICAgIFRoaXMtPmJEZWNvbXByZXNzID0gVFJVRTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBkZWxldGluZyBob2xlIHBhcnQgKi8KICAgICAgICBsZW4gLT0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoOwogICAgICAgIEFWSUZJTEVfUmVtb3ZlU3RyZWFtKFRoaXMsc3RyZWFtTnIpOwogICAgICB9CiAgICB9IGVsc2UgaWYgKEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIDw9IHN0cmVhbVBvcyArIGxlbikgewogICAgICAvKiBkZWxldGluZyBhdCBlbmQgb2YgYSBwYXJ0ICovCiAgICAgIERXT1JEIGNvdW50ID0gRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgLSBzdHJlYW1Qb3M7CiAgICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC09IGNvdW50OwogICAgICBsZW4gICAgICAgICAgICAgICAgICAtPSBjb3VudDsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KICAgICAgICBzdHJlYW1Qb3MgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKICAgIH0gZWxzZSB7CiAgICAgIC8qIHNwbGl0dGluZyAqLwogICAgICBpZiAoVGhpcy0+blN0cmVhbXMgKyAxID49IFRoaXMtPm5UYWJsZVNpemUpIHsKICAgICAgICBUaGlzLT5wU3RyZWFtcyA9CiAgICAgICAgICBHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPnBTdHJlYW1zLCAoVGhpcy0+blRhYmxlU2l6ZSArIDMyKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpLCBHTUVNX1NIQVJFfEdITkQpOwogICAgICAgIGlmIChUaGlzLT5wU3RyZWFtcyA9PSBOVUxMKQogICAgICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgICAgVGhpcy0+blRhYmxlU2l6ZSArPSAzMjsKICAgICAgfQogICAgICBtZW1tb3ZlKFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIgKyAxLCBUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yLAogICAgICAgICAgICAgIChUaGlzLT5uU3RyZWFtcyAtIHN0cmVhbU5yKSAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICAgICAgVGhpcy0+blN0cmVhbXMrKzsKCiAgICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgMV0ucFN0cmVhbSk7CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgMV0uZHdTdGFydCAgPSBzdHJlYW1Qb3MgKyBsZW47CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgMV0uZHdMZW5ndGggPQogICAgICAgIEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIC0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5kd1N0YXJ0OwoKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KICAgICAgICBzdHJlYW1Qb3MgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKICAgICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gbGVuOwogICAgICBsZW4gPSAwOwogICAgfQogIH0KCiAgVGhpcy0+c0luZm8uZHdFZGl0Q291bnQrKzsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ29weShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUNPTV9USElTKElBVklFZGl0U3RyZWFtSW1wbCxpZmFjZSk7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBwRWRpdDsKICBIUkVTVUxUIGhyOwogIExPTkcgc3RhcnQgPSAwOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogICpwcFJlc3VsdCA9IE5VTEw7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8ICpwbFN0YXJ0IDwgMCB8fCAqcGxMZW5ndGggPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY2hlY2sgYm91bmRzICovCiAgaWYgKCooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgKihMUERXT1JEKXBsTGVuZ3RoID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKCooTFBEV09SRClwbFN0YXJ0IDwgVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgKihMUERXT1JEKXBsTGVuZ3RoIC09IFRoaXMtPnNJbmZvLmR3U3RhcnQgLSAqKExQRFdPUkQpcGxTdGFydDsKICAgICooTFBEV09SRClwbFN0YXJ0ICAgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgaWYgKCpwbExlbmd0aCA8IDApCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgfQogIGlmICgqKExQRFdPUkQpcGxTdGFydCArICooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgICooTFBEV09SRClwbExlbmd0aCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCAtCiAgICAgICooTFBEV09SRClwbFN0YXJ0OwoKICBwRWRpdCA9IChJQVZJRWRpdFN0cmVhbUltcGwqKUFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShOVUxMKTsKICBpZiAocEVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IElBVklFZGl0U3RyZWFtX1Bhc3RlKChQQVZJRURJVFNUUkVBTSlwRWRpdCwmc3RhcnQscGxMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICpwbFN0YXJ0ICsgKnBsTGVuZ3RoKTsKICAqcGxTdGFydCA9IHN0YXJ0OwogIGlmIChGQUlMRUQoaHIpKQogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZSgoUEFWSUVESVRTVFJFQU0pcEVkaXQpOwogIGVsc2UKICAgICpwcFJlc3VsdCA9IChQQVZJU1RSRUFNKSZwRWRpdC0+aUFWSVN0cmVhbTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSBwU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGxTdGFydCxMT05HIGxMZW5ndGgpCnsKICBJQ09NX1RISVMoSUFWSUVkaXRTdHJlYW1JbXBsLGlmYWNlKTsKICBBVklTVFJFQU1JTkZPVyAgICAgIHNyY0luZm87CiAgSUVkaXRTdHJlYW1JbnRlcm5hbCpwSW50ZXJuYWwgPSBOVUxMOwogIElBVklFZGl0U3RyZWFtSW1wbCAqcEVkaXQgPSBOVUxMOwogIFBBVklTVFJFQU0gICAgICAgICAgcFN0cmVhbTsKICBEV09SRCAgICAgICAgICAgICAgIHN0YXJ0UG9zLCBlbmRQb3MsIHN0cmVhbU5yLCBuLCBuU3RyZWFtczsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcCwlbGQsJWxkKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLAoJcFNvdXJjZSxsU3RhcnQsbExlbmd0aCk7CgogIGlmIChwU291cmNlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8ICpwbFN0YXJ0IDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8ICpwbFN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsgLyogQ2FuJ3QgcGFzdGUgd2l0aCBob2xlcyAqLwogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBTb3VyY2UsICZzcmNJbmZvLCBzaXplb2Yoc3JjSW5mbykpKSkKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgaWYgKGxTdGFydCA8IHNyY0luZm8uZHdTdGFydCB8fCBsU3RhcnQgPj0gc3JjSW5mby5kd1N0YXJ0ICsgc3JjSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gMCkgewogICAgLyogVGhpcyBzdHJlYW0gaXMgZW1wdHkgKi8KICAgIElBVklTdHJlYW1fSW5mbyhwU291cmNlLCAmVGhpcy0+c0luZm8sIHNpemVvZihUaGlzLT5zSW5mbykpOwogICAgVGhpcy0+c0luZm8uZHdTdGFydCAgPSAqcGxTdGFydDsKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gMDsKICB9CiAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgIT0gc3JjSW5mby5mY2NUeXBlKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogZGlmZmVyZW50IHN0cmVhbSB0eXBlcyAqLwogIGlmIChsTGVuZ3RoID09IC0xKSAvKiBDb3B5IHRoZSBob2xlIHN0cmVhbSAqLwogICAgbExlbmd0aCA9IHNyY0luZm8uZHdMZW5ndGg7CiAgaWYgKGxTdGFydCArIGxMZW5ndGggPiBzcmNJbmZvLmR3U3RhcnQgKyBzcmNJbmZvLmR3TGVuZ3RoKQogICAgbExlbmd0aCA9IHNyY0luZm8uZHdTdGFydCArIHNyY0luZm8uZHdMZW5ndGggLSBsU3RhcnQ7CiAgaWYgKGxMZW5ndGggKyAqcGxTdGFydCA+PSAweDgwMDAwMDAwKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIHN0cmVhbXR5cGUgc3BlY2lmaWMgdGVzdHMgKi8KICBpZiAoc3JjSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgRFdPUkQgc2l6ZTsKCiAgICBzaXplID0gc3JjSW5mby5yY0ZyYW1lLnJpZ2h0IC0gc3JjSW5mby5yY0ZyYW1lLmxlZnQ7CiAgICBpZiAoc2l6ZSAhPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0IC0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0KQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBGSVhNRTogQ2FuJ3QgR2V0RnJhbWUgY29udmVydCBpdD8gKi8KICAgIHNpemUgPSBzcmNJbmZvLnJjRnJhbWUuYm90dG9tIC0gc3JjSW5mby5yY0ZyYW1lLnRvcDsKICAgIGlmIChzaXplICE9IFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tIC0gVGhpcy0+c0luZm8ucmNGcmFtZS50b3ApCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIEZJWE1FOiBDYW4ndCBHZXRGcmFtZSBjb252ZXJ0IGl0PyAqLwogIH0gZWxzZSBpZiAoc3JjSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykgewogICAgaWYgKCEgQVZJRklMRV9Gb3JtYXRzRXF1YWwoKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW0sIHBTb3VyY2UpKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0gZWxzZSB7CiAgICAvKiBGSVhNRTogc3RyZWFtdHlwZU1JREkgYW5kIHN0cmVhbXR5cGVURVhUICovCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogdHJ5IHRvIGdldCBhbiBJRWRpdFN0cmVhbUludGVybmFsIGludGVyZmFjZSAqLwogIGlmIChTVUNDRUVERUQoSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU291cmNlLCAmSUlEX0lFZGl0U3RyZWFtSW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQqKSZwSW50ZXJuYWwpKSkgewogICAgcEludGVybmFsLT5scFZ0YmwtPkdldEVkaXRTdHJlYW1JbXBsKHBJbnRlcm5hbCwgKExQVk9JRCopJnBFZGl0KTsKICAgIHBJbnRlcm5hbC0+bHBWdGJsLT5SZWxlYXNlKHBJbnRlcm5hbCk7CiAgfQoKICAvKiBmb3IgdmlkZW8gbXVzdCBjaGVjayBmb3IgY2hhbmdlIG9mIGZvcm1hdCAqLwogIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgaWYgKCEgVGhpcy0+YkRlY29tcHJlc3MpIHsKICAgICAgLyogTmVlZCB0byBkZWNvbXByZXNzIGlmIGFueSBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgbWF0Y2hlczoKICAgICAgICogIC0gcFNvdXJjZSBpcyBhbiBlZGl0YWJsZSBzdHJlYW0gd2hpY2ggZGVjb21wcmVzc2VzCiAgICAgICAqICAtIHRoZSBuZWFyZXN0IGtleWZyYW1lIG9mIHBTb3VyY2UgaXNuJ3QgbFN0YXJ0CiAgICAgICAqICAtIHRoZSBuZWFyZXN0IGtleWZyYW1lIG9mIHRoaXMgc3RyZWFtIGlzbid0ICpwbFN0YXJ0CiAgICAgICAqICAtIHRoZSBmb3JtYXQgb2YgcFNvdXJjZSBkb2Vzbid0IG1hdGNoIHRoaXMgb25lCiAgICAgICAqLwogICAgICBpZiAoKHBFZGl0ICE9IE5VTEwgJiYgcEVkaXQtPmJEZWNvbXByZXNzKSB8fAoJICBBVklTdHJlYW1OZWFyZXN0S2V5RnJhbWUocFNvdXJjZSwgbFN0YXJ0KSAhPSBsU3RhcnQgfHwKCSAgQVZJU3RyZWFtTmVhcmVzdEtleUZyYW1lKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCAqcGxTdGFydCkgIT0gKnBsU3RhcnQgfHwKCSAgKFRoaXMtPm5TdHJlYW1zID4gMCAmJiAhQVZJRklMRV9Gb3JtYXRzRXF1YWwoKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW0sIHBTb3VyY2UpKSkgewoJLyogVXNlIGZpcnN0IHN0cmVhbSBwYXJ0IHRvIGdldCBmb3JtYXQgdG8gY29udmVydCBldmVyeXRoaW5nIHRvICovCglBVklGSUxFX1JlYWRGcmFtZShUaGlzLCBUaGlzLT5wU3RyZWFtc1swXS5wU3RyZWFtLAoJCQkgIFRoaXMtPnBTdHJlYW1zWzBdLmR3U3RhcnQpOwoKCS8qIENoZWNrIGlmIHdlIGNvdWxkIGNvbnZlcnQgdGhlIHNvdXJjZSBzdHJlYW1zIHRvIHRoZSBkaXNpcmVkIGZvcm1hdC4uLiAqLwoJaWYgKHBFZGl0ICE9IE5VTEwpIHsKCSAgaWYgKEZBSUxFRChBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKHBFZGl0LCBsU3RhcnQsICZwU3RyZWFtLAoJCQkJCSAgICAgICAmc3RhcnRQb3MsICZzdHJlYW1OciwgVFJVRSkpKQoJICAgIHJldHVybiBBVklFUlJfSU5URVJOQUw7CgkgIGZvciAobiA9IGxTdGFydDsgbiA8IGxTdGFydCArIGxMZW5ndGg7IHN0cmVhbU5yKyspIHsKCSAgICBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcEVkaXQtPnBTdHJlYW1zW3N0cmVhbU5yXS5wU3RyZWFtLCBzdGFydFBvcykgPT0gTlVMTCkKCSAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoJICAgIHN0YXJ0UG9zID0gcEVkaXQtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwoJICAgIG4gKz0gcEVkaXQtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aDsKCSAgfQoJfSBlbHNlIGlmIChBVklGSUxFX1JlYWRGcmFtZShUaGlzLCBwU291cmNlLCBsU3RhcnQpID09IE5VTEwpCgkgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKCVRoaXMtPmJEZWNvbXByZXNzICAgICAgPSBUUlVFOwoJVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9IDA7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcFNvdXJjZSwgbFN0YXJ0KSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsgLyogQ2FuJ3QgY29udmVydCBzb3VyY2UgdG8gb3duIGZvcm1hdCAqLwogIH0gLyogRklYTUU6IHNvbWV0aGluZyBzcGVjaWFsIGZvciB0aGUgb3RoZXIgZm9ybWF0cz8gKi8KCiAgLyogTWFrZSBzdXJlIHdlIGhhdmUgZW5vdWdoIG1lbW9yeSBmb3IgcGFydHMgKi8KICBpZiAocEVkaXQgIT0gTlVMTCkgewogICAgRFdPUkQgbkxhc3RTdHJlYW07CgogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0ICsgbExlbmd0aCwgJnBTdHJlYW0sCgkJCSAgICAgICZlbmRQb3MsICZuTGFzdFN0cmVhbSwgVFJVRSk7CiAgICBBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKHBFZGl0LCBsU3RhcnQsICZwU3RyZWFtLAoJCQkgICAgICAmc3RhcnRQb3MsICZzdHJlYW1OciwgRkFMU0UpOwogICAgaWYgKG5MYXN0U3RyZWFtID09IHN0cmVhbU5yKQogICAgICBuTGFzdFN0cmVhbSsrOwoKICAgIG5TdHJlYW1zID0gbkxhc3RTdHJlYW0gLSBzdHJlYW1OcjsKICB9IGVsc2UgCiAgICBuU3RyZWFtcyA9IDE7CiAgaWYgKFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgKyAxID4gVGhpcy0+blRhYmxlU2l6ZSkgewogICAgbiA9IFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgKyAzMzsKCiAgICBUaGlzLT5wU3RyZWFtcyA9CiAgICAgIEdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+cFN0cmVhbXMsIG4gKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSwgR01FTV9TSEFSRXxHSE5EKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPm5UYWJsZVNpemUgPSBuOwogIH0KCiAgaWYgKHBsTGVuZ3RoICE9IE5VTEwpCiAgICAqcGxMZW5ndGggPSBsTGVuZ3RoOwoKICAvKiBub3cgZG8gdGhlIHJlYWwgd29yayAqLwogIGlmIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPiAqcGxTdGFydCkgewogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCAqcGxTdGFydCwgJnBTdHJlYW0sCgkJCSAgICAgICZzdGFydFBvcywgJnN0cmVhbU5yLCBGQUxTRSk7CiAgICBpZiAoc3RhcnRQb3MgIT0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQpIHsKICAgICAgLyogc3BsaXQgc3RyZWFtIHN0cmVhbU5yIGF0IHN0YXJ0UG9zICovCiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIG5TdHJlYW1zICsgMSwKCSAgICAgIFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsCgkgICAgICAoVGhpcy0+blN0cmVhbXMgKyBuU3RyZWFtcyAtIHN0cmVhbU5yICsgMSkgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CgogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDJdLmR3TGVuZ3RoID0KCUVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIgKyAyKSAtIHN0YXJ0UG9zOwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDJdLmR3U3RhcnQgPSBzdGFydFBvczsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KCXN0YXJ0UG9zIC0gVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQ7CiAgICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5wU3RyZWFtKTsKICAgICAgc3RyZWFtTnIrKzsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGluc2VydCBiZWZvcmUgc3RyZWFtIGF0IHN0cmVhbU5yICovCiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIG5TdHJlYW1zLCBUaGlzLT5wU3RyZWFtcyArIHN0cmVhbU5yLAoJICAgICAgKFRoaXMtPm5TdHJlYW1zICsgblN0cmVhbXMgLSBzdHJlYW1OcikgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICB9CiAgfSBlbHNlIC8qIGFwcGVuZCB0aGUgc3RyZWFtcyAqLwogICAgc3RyZWFtTnIgPSBUaGlzLT5uU3RyZWFtczsKCiAgaWYgKHBFZGl0ICE9IE5VTEwpIHsKICAgIC8qIGluc2VydCB0aGUgcGFydHMgb2YgdGhlIGVkaXRhYmxlIHN0cmVhbSBpbnN0ZWFkIG9mIGl0c2VsZiAqLwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0ICsgbExlbmd0aCwgJnBTdHJlYW0sCgkJCSAgICAgICZlbmRQb3MsIE5VTEwsIEZBTFNFKTsKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCwgJnBTdHJlYW0sICZzdGFydFBvcywgJm4sIEZBTFNFKTsKCiAgICBtZW1jcHkoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciwgcEVkaXQtPnBTdHJlYW1zICsgbiwKCSAgIG5TdHJlYW1zICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgaWYgKFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0IDwgc3RhcnRQb3MpIHsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoID0KCUVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIC0gc3RhcnRQb3M7CiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICA9IHN0YXJ0UG9zOwogICAgfQogICAgaWYgKGVuZFBvcyA8IEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIgKyBuU3RyZWFtcykpCiAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgblN0cmVhbXNdLmR3TGVuZ3RoID0KCWVuZFBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgblN0cmVhbXNdLmR3U3RhcnQ7CiAgfSBlbHNlIHsKICAgIC8qIGEgc2ltcGxlIHN0cmVhbSAqLwogICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLnBTdHJlYW0gID0gcFNvdXJjZTsKICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICA9IGxTdGFydDsKICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd0xlbmd0aCA9IGxMZW5ndGg7CiAgfQoKICBmb3IgKG4gPSAwOyBuIDwgblN0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyBuXS5wU3RyZWFtKTsKICAgIGlmICgwIDwgc3RyZWFtTnIgKyBuICYmCglUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIG4gLSAxXS5wU3RyZWFtICE9IFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yICsgbl0ucFN0cmVhbSkgewogICAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKICAgICAgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCsrOwogICAgfQogIH0KICBUaGlzLT5zSW5mby5kd0VkaXRDb3VudCsrOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICs9IGxMZW5ndGg7CiAgVGhpcy0+blN0cmVhbXMgKz0gblN0cmVhbXM7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkNsb25lKElBVklFZGl0U3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUNPTV9USElTKElBVklFZGl0U3RyZWFtSW1wbCxpZmFjZSk7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBwRWRpdDsKICBEV09SRCBpOwoKICBUUkFDRSgiKCVwLCVwKVxuIixpZmFjZSxwcFJlc3VsdCk7CgogIGlmIChwcFJlc3VsdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICAqcHBSZXN1bHQgPSBOVUxMOwoKICBwRWRpdCA9IChJQVZJRWRpdFN0cmVhbUltcGwqKUFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShOVUxMKTsKICBpZiAocEVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIGlmIChUaGlzLT5uU3RyZWFtcyA+IHBFZGl0LT5uVGFibGVTaXplKSB7CiAgICBwRWRpdC0+cFN0cmVhbXMgPSBHbG9iYWxSZUFsbG9jUHRyKHBFZGl0LT5wU3RyZWFtcywgVGhpcy0+blN0cmVhbXMgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSxHTUVNX1NIQVJFfEdITkQpOwogICAgaWYgKHBFZGl0LT5wU3RyZWFtcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIHBFZGl0LT5uVGFibGVTaXplID0gVGhpcy0+blN0cmVhbXM7CiAgfQogIHBFZGl0LT5uU3RyZWFtcyA9IFRoaXMtPm5TdHJlYW1zOwogIG1lbWNweShwRWRpdC0+cFN0cmVhbXMsIFRoaXMtPnBTdHJlYW1zLAogICAgICAgICBUaGlzLT5uU3RyZWFtcyAqIHNpemVvZihFZGl0U3RyZWFtVGFibGUpKTsKICBtZW1jcHkoJnBFZGl0LT5zSW5mbywmVGhpcy0+c0luZm8sc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgZm9yIChpID0gMDsgaSA8IFRoaXMtPm5TdHJlYW1zOyBpKyspIHsKICAgIGlmIChwRWRpdC0+cFN0cmVhbXNbaV0ucFN0cmVhbSAhPSBOVUxMKQogICAgICBJQVZJU3RyZWFtX0FkZFJlZihwRWRpdC0+cFN0cmVhbXNbaV0ucFN0cmVhbSk7CiAgfQoKICAqcHBSZXN1bHQgPSAoUEFWSVNUUkVBTSkmcEVkaXQtPmlBVklTdHJlYW07CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblNldEluZm8oSUFWSUVkaXRTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBVklTVFJFQU1JTkZPVyBhc2ksTE9ORyBzaXplKQp7CiAgSUNPTV9USElTKElBVklFZGl0U3RyZWFtSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhc2ksc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplICE9IHNpemVvZihBVklTVFJFQU1JTkZPVykpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CiAgaWYgKGFzaS0+ZHdTY2FsZSA9PSAwIHx8IGFzaS0+ZHdSYXRlID09IDAgfHwgKExPTkcpYXNpLT5kd1F1YWxpdHkgPCAtMSB8fAogICAgICBhc2ktPmR3UXVhbGl0eSA+IElDUVVBTElUWV9ISUdIKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgVGhpcy0+c0luZm8ud0xhbmd1YWdlID0gYXNpLT53TGFuZ3VhZ2U7CiAgVGhpcy0+c0luZm8ud1ByaW9yaXR5ID0gYXNpLT53UHJpb3JpdHk7CiAgVGhpcy0+c0luZm8uZHdTdGFydCAgID0gYXNpLT5kd1N0YXJ0OwogIGlmIChhc2ktPmR3UmF0ZSAhPSAwKQogICAgVGhpcy0+c0luZm8uZHdSYXRlICA9IGFzaS0+ZHdSYXRlOwogIGlmIChhc2ktPmR3U2NhbGUgIT0gMCkKICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUgPSBhc2ktPmR3U2NhbGU7CiAgaWYgKGFzaS0+ZHdRdWFsaXR5IDw9IElDUVVBTElUWV9ISUdIKQogICAgVGhpcy0+c0luZm8uZHdRdWFsaXR5ID0gSUNRVUFMSVRZX0hJR0g7CiAgQ29weVJlY3QoJlRoaXMtPnNJbmZvLnJjRnJhbWUsICZhc2ktPnJjRnJhbWUpOwogIG1lbWNweSgmVGhpcy0+c0luZm8uc3pOYW1lLCAmYXNpLT5zek5hbWUsIHNpemVvZihhc2ktPnN6TmFtZSkpOwogIFRoaXMtPnNJbmZvLmR3RWRpdENvdW50Kys7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaikKewogIElDT01fVEhJUyhJRWRpdEFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUscmVmaWlkLG9iaik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKQp7CiAgSUNPTV9USElTKElFZGl0QVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9BZGRSZWYoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qaWZhY2UpCnsKICBJQ09NX1RISVMoSUVkaXRBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1JlbGVhc2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKChJRWRpdEFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFlOwoKICBpZiAobFBhcmFtMiAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpIHsKICAgIFRoaXMtPnBTdHJlYW1zID0KICAgICAgR2xvYmFsQWxsb2NQdHIoR01FTV9TSEFSRXxHSE5ELCAyNTYgKiBzaXplb2YoRWRpdFN0cmVhbVRhYmxlKSk7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5uVGFibGVTaXplID0gMjU2OwogIH0KCiAgaWYgKGxQYXJhbTEgIT0gMCkgewogICAgSUFWSVN0cmVhbV9JbmZvKChQQVZJU1RSRUFNKWxQYXJhbTEsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgICBJQVZJU3RyZWFtX0FkZFJlZigoUEFWSVNUUkVBTSlsUGFyYW0xKTsKICAgIFRoaXMtPnBTdHJlYW1zWzBdLnBTdHJlYW0gID0gKFBBVklTVFJFQU0pbFBhcmFtMTsKICAgIFRoaXMtPnBTdHJlYW1zWzBdLmR3U3RhcnQgID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIFRoaXMtPnBTdHJlYW1zWzBdLmR3TGVuZ3RoID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgICBUaGlzLT5uU3RyZWFtcyA9IDE7CiAgfQogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSkKewogIElDT01fVEhJUyhJRWRpdEFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsaWZhY2UscHNpLHNpemUpOwoKICBhc3NlcnQoVGhpcy0+cGFlICE9IE5VTEwpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgaWYgKFRoaXMtPnBhZS0+YkRlY29tcHJlc3MpCiAgICBUaGlzLT5wYWUtPnNJbmZvLmZjY0hhbmRsZXIgPSAwOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+cGFlLT5zSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+cGFlLT5zSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPnBhZS0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBmbGFncykKewogIElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcyA9ICgoSUVkaXRBVklTdHJlYW1JbXBsKiBjb25zdClpZmFjZSktPnBhZTsKICBQQVZJU1RSRUFNIHN0cmVhbTsKICBEV09SRCAgICAgIHN0cmVhbVBvcywgc3RyZWFtTnI7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkKICAgIHBvcyA9IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQ7CgogIC8qIG91dHNpZGUgb2Ygc3RyZWFtPyAqLwogIGlmIChwb3MgPCAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0IHx8CiAgICAgIChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgKyAoTE9ORylUaGlzLT5zSW5mby5kd0xlbmd0aCA8PSBwb3MpCiAgICByZXR1cm4gLTE7CgogIC8qIG1hcCBvdXIgcG9zaXRpb24gdG8gYSBzdHJlYW0gYW5kIHBvc2l0aW9uIGluIGl0ICovCiAgaWYgKEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoVGhpcywgcG9zLCAmc3RyZWFtLCAmc3RyZWFtUG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdHJlYW1OciwgVFJVRSkpCiAgICByZXR1cm4gLTE7IC8qIGRvZXNuJ3QgZXhpc3QgKi8KCiAgaWYgKFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAvKiBvbmx5IG9uZSBzdHJlYW0gLS0gZm9ybWF0IGNoYW5nZXMgb25seSBhdCBzdGFydCAqLwogICAgaWYgKGZsYWdzICYgRklORF9GT1JNQVQpCiAgICAgIHJldHVybiAoZmxhZ3MgJiBGSU5EX05FWFQgPyAtMSA6IDApOwoKICAgIC8qIEZJWE1FOiBtYXAgcG9zaXRpb25zIGJhY2sgdG8gdXMgKi8KICAgIHJldHVybiBJQVZJU3RyZWFtX0ZpbmRTYW1wbGUoc3RyZWFtLCBzdHJlYW1Qb3MsIGZsYWdzKTsKICB9IGVsc2UgewogICAgLyogYXNzdW1lIGNoYW5nZSBvZiBmb3JtYXQgZXZlcnkgZnJhbWUgKi8KICAgIHJldHVybiBwb3M7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGZvcm1hdCxMT05HKmZtdHNpemUpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgTFBCSVRNQVBJTkZPSEVBREVSICBscDsKICBQQVZJU1RSRUFNICAgICAgICAgIHN0cmVhbTsKICBEV09SRCAgICAgICAgICAgICAgIG47CiAgSFJFU1VMVCAgICAgICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLGlmYWNlLHBvcyxmb3JtYXQsZm10c2l6ZSk7CgogIGlmIChmbXRzaXplID09IE5VTEwgfHwgcG9zIDwgVGhpcy0+c0luZm8uZHdTdGFydCB8fAogICAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPD0gcG9zKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogZmluZCBzdHJlYW0gY29ycmVzcG9uZGluZyB0byBwb3NpdGlvbiAqLwogIGhyID0gQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBwb3MsICZzdHJlYW0sICZuLCBOVUxMLCBGQUxTRSk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKQogICAgcmV0dXJuIElBVklTdHJlYW1fUmVhZEZvcm1hdChzdHJlYW0sIG4sIGZvcm1hdCwgZm10c2l6ZSk7CgogIGxwID0gKExQQklUTUFQSU5GT0hFQURFUilBVklGSUxFX1JlYWRGcmFtZShUaGlzLCBzdHJlYW0sIG4pOwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICBpZiAobHAtPmJpQml0Q291bnQgPD0gOCkgewogICAgbiAgPSAobHAtPmJpQ2xyVXNlZCA+IDAgPyBscC0+YmlDbHJVc2VkIDogMSA8PCBscC0+YmlCaXRDb3VudCk7CiAgICBuICo9IHNpemVvZihSR0JRVUFEKTsKICB9IGVsc2UKICAgIG4gPSAwOwogIG4gKz0gbHAtPmJpU2l6ZTsKICAKICBtZW1jcHkoZm9ybWF0LCBscCwgbWluKChMT05HKW4sICpmbXRzaXplKSk7CiAgaHIgPSAoKExPTkcpbiA+ICpmbXRzaXplID8gQVZJRVJSX0JVRkZFUlRPT1NNQUxMIDogQVZJRVJSX09LKTsKICAqZm10c2l6ZSA9IG47CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSkKewogIFRSQUNFKCIoJXAsJWxkLCVwLCVsZClcbiIsaWZhY2UscG9zLGZvcm1hdCxmb3JtYXRzaXplKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLExPTkcqYnl0ZXNyZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqc2FtcGxlc3JlYWQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgUEFWSVNUUkVBTSBzdHJlYW07CiAgRFdPUkQgICBzdHJlYW1Qb3MsIHN0cmVhbU5yOwogIExPTkcgICAgcmVhZEJ5dGVzLCByZWFkU2FtcGxlcywgY291bnQ7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwlcCwlcCkgLS0gMHglMDhsWFxuIixpZmFjZSxzdGFydCxzYW1wbGVzLAogICAgICAgIGJ1ZmZlcixidWZmZXJzaXplLGJ5dGVzcmVhZCxzYW1wbGVzcmVhZCxUaGlzLT5zSW5mby5mY2NUeXBlKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKICBpZiAoYnVmZmVyc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CiAgaWYgKChEV09SRClzdGFydCA8IFRoaXMtPnNJbmZvLmR3U3RhcnQgfHwKICAgICAgVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKERXT1JEKXN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKCEgVGhpcy0+YkRlY29tcHJlc3MpIHsKICAgIC8qIGF1ZGlvIGxpa2UgZGF0YSAtLSBzYW1wbGUtYmFzZWQgKi8KICAgIGRvIHsKICAgICAgaWYgKHNhbXBsZXMgPT0gMCkKICAgICAgICByZXR1cm4gQVZJRVJSX09LOyAvKiBub3RoaW5nIGF0IGFsbCBvciBhbHJlYWR5IGRvbmUgKi8KCiAgICAgIGlmIChGQUlMRUQoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBzdGFydCwgJnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdHJlYW1Qb3MsICZzdHJlYW1OciwgRkFMU0UpKSkKICAgICAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICAgICAgLyogbGltaXQgdG8gZW5kIG9mIHRoZSBzdHJlYW0gKi8KICAgICAgY291bnQgPSBzYW1wbGVzOwogICAgICBpZiAoc3RyZWFtUG9zICsgY291bnQgPiBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSkKICAgICAgICBjb3VudCA9IEVkaXRTdHJlYW1FbmQoVGhpcywgc3RyZWFtTnIpIC0gc3RyZWFtUG9zOwoKICAgICAgaHIgPSBJQVZJU3RyZWFtX1JlYWQoc3RyZWFtLCBzdHJlYW1Qb3MsIGNvdW50LCBidWZmZXIsIGJ1ZmZlcnNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZWFkQnl0ZXMsICZyZWFkU2FtcGxlcyk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgIHJldHVybiBocjsKICAgICAgaWYgKHJlYWRCeXRlcyA9PSAwICYmIHJlYWRTYW1wbGVzID09IDAgJiYgY291bnQgIT0gMCkKICAgICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOyAvKiBmb3IgYmFkIHN0cmVhbSBpbXBsZW1lbnRhdGlvbnMgKi8KCiAgICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAgICpzYW1wbGVzcmVhZCArPSByZWFkU2FtcGxlczsKICAgICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAgICpieXRlc3JlYWQgKz0gcmVhZEJ5dGVzOwogICAgICBpZiAoYnVmZmVyICE9IE5VTEwpIHsKICAgICAgICAoTFBCWVRFKWJ1ZmZlciArPSByZWFkQnl0ZXM7CiAgICAgICAgYnVmZmVyc2l6ZSAgICAgLT0gcmVhZEJ5dGVzOwogICAgICB9CiAgICAgIHN0YXJ0ICAgKz0gY291bnQ7CiAgICAgIHNhbXBsZXMgLT0gY291bnQ7CiAgICB9IHdoaWxlIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPiBzdGFydCk7CiAgfSBlbHNlIHsKICAgIC8qIHZpZGVvIGxpa2UgZGF0YSAtLSBmcmFtZS1iYXNlZCAqLwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwOwoKICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CgogICAgaWYgKEZBSUxFRChBVklGSUxFX0ZpbmRTdHJlYW1JblRhYmxlKFRoaXMsIHN0YXJ0LCAmc3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdHJlYW1Qb3MsICZzdHJlYW1OciwgRkFMU0UpKSkKICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgICBscCA9IEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHN0cmVhbSwgc3RyZWFtUG9zKTsKICAgIGlmIChscCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICAgIGlmIChidWZmZXIgIT0gTlVMTCkgewogICAgICAvKiBuZWVkIHNpemUgb2YgZm9ybWF0IHRvIHNraXAgKi8KICAgICAgaWYgKGxwLT5iaUJpdENvdW50IDw9IDgpIHsKICAgICAgICBjb3VudCAgPSBscC0+YmlDbHJVc2VkID4gMCA/IGxwLT5iaUNsclVzZWQgOiAxIDw8IGxwLT5iaUJpdENvdW50OwogICAgICAgIGNvdW50ICo9IHNpemVvZihSR0JRVUFEKTsKICAgICAgfSBlbHNlCiAgICAgICAgY291bnQgPSAwOwogICAgICBjb3VudCArPSBscC0+YmlTaXplOwoKICAgICAgaWYgKGJ1ZmZlcnNpemUgPCBscC0+YmlTaXplSW1hZ2UpCiAgICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICAgICAgbWVtY3B5KGJ1ZmZlciwgKExQQllURSlscCArIGNvdW50LCBscC0+YmlTaXplSW1hZ2UpOwogICAgfQoKICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IGxwLT5iaVNpemVJbWFnZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSAxOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXB3cml0dGVuLExPTkcqYnl0ZXN3cml0dGVuKQp7CiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwweCUwOGxYLCVwLCVwKVxuIixpZmFjZSxzdGFydCxzYW1wbGVzLGJ1ZmZlciwKICAgICAgICBidWZmZXJzaXplLGZsYWdzLHNhbXB3cml0dGVuLGJ5dGVzd3JpdHRlbik7CgogIC8qIGJlIHN1cmUgcmV0dXJuIHBhcmFtZXRlcnMgaGF2ZSBjb3JyZWN0IHZhbHVlcyAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcykKewogIElDT01fVEhJUyhJRWRpdEFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLGlmYWNlLHN0YXJ0LHNhbXBsZXMpOwoKICByZXR1cm4gSUFWSUVkaXRTdHJlYW1fQ3V0KChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlLCZzdGFydCwmc2FtcGxlcyxOVUxMKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HICpscHJlYWQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwqIGNvbnN0IFRoaXMgPSAoKElFZGl0QVZJU3RyZWFtSW1wbCogY29uc3QpaWZhY2UpLT5wYWU7CiAgRFdPUkQgbjsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIixpZmFjZSxmY2MsbHAsbHByZWFkKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscCA9PSBOVUxMIHx8IGxwcmVhZCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogc2ltcGx5IGFzayBldmVyeSBzdHJlYW0gYW5kIHJldHVybiB0aGUgZmlyc3QgYmxvY2sgZm91bmQgKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+blN0cmVhbXM7IG4rKykgewogICAgSFJFU1VMVCBociA9IElBVklTdHJlYW1fUmVhZERhdGEoVGhpcy0+cFN0cmVhbXNbbl0ucFN0cmVhbSxmY2MsbHAsbHByZWFkKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgKmxwcmVhZCA9IDA7CiAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJWxkKVxuIixpZmFjZSxmY2MsbHAsc2l6ZSk7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgbGVuKQp7CiAgSUNPTV9USElTKElFZGl0QVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxpbmZvLGxlbik7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9TZXRJbmZvKChJQVZJRWRpdFN0cmVhbSopVGhpcy0+cGFlLGluZm8sbGVuKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5RdWVyeUludGVyZmFjZShJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaikKewogIElDT01fVEhJUyhJRWRpdFN0cmVhbUludGVybmFsSW1wbCxpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWUgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRWRpdFN0cmVhbV9RdWVyeUludGVyZmFjZSgoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mbkFkZFJlZihJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKQp7CiAgSUNPTV9USElTKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX0FkZFJlZigoSUFWSUVkaXRTdHJlYW0qKVRoaXMtPnBhZSk7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUmVsZWFzZShJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKQp7CiAgSUNPTV9USElTKElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklFZGl0U3RyZWFtX1JlbGVhc2UoKElBVklFZGl0U3RyZWFtKilUaGlzLT5wYWUpOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5HZXRFZGl0U3RyZWFtSW1wbChJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlLExQVk9JRCpwcGltcGwpCnsKICBJQ09NX1RISVMoSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVwKSAtPiAlcFxuIiwgaWZhY2UsIHBwaW1wbCwgVGhpcy0+cGFlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZSAhPSBOVUxMKTsKICBhc3NlcnQocHBpbXBsICE9IE5VTEwpOwoKICAqcHBpbXBsID0gVGhpcy0+cGFlOwogIHJldHVybiBBVklFUlJfT0s7Cn0K