LyoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBpbnRlcm5hbCBpbnRlcmZhY2UgdG8gZ2V0IGFjY2VzcyB0byB0YWJsZSBvZiBzdHJlYW0gaW4gYW4gZWRpdGFibGUgc3RyZWFtICovCgp0eXBlZGVmIHN0cnVjdCBfRWRpdFN0cmVhbVRhYmxlIHsKICBQQVZJU1RSRUFNIHBTdHJlYW07ICAvKiBzdHJlYW0gd2hpY2ggY29udGFpbnMgdGhlIGRhdGEgKi8KICBEV09SRCAgICAgIGR3U3RhcnQ7ICAvKiB3aGVyZSBzdGFydHMgdGhlIHBhcnQgd2hpY2ggaXMgYWxzbyBvdXIgKi8KICBEV09SRCAgICAgIGR3TGVuZ3RoOyAvKiBob3cgbWFueSBpcyBhbHNvIGluIHRoaXMgc3RyZWFtICovCn0gRWRpdFN0cmVhbVRhYmxlOwoKI2RlZmluZSBJTlRFUkZBQ0UgSUVkaXRTdHJlYW1JbnRlcm5hbApERUNMQVJFX0lOVEVSRkFDRV8oSUVkaXRTdHJlYW1JbnRlcm5hbCxJVW5rbm93bikKewogICAgLyoqKiBJVW5rbm93biBtZXRob2RzICoqKi8KICAgIFNURE1FVEhPRF8oSFJFU1VMVCxRdWVyeUludGVyZmFjZSkoVEhJU18gUkVGSUlEIHJpaWQsIHZvaWQqKiBwcHZPYmplY3QpIFBVUkU7CiAgICBTVERNRVRIT0RfKFVMT05HLEFkZFJlZikoVEhJUykgUFVSRTsKICAgIFNURE1FVEhPRF8oVUxPTkcsUmVsZWFzZSkoVEhJUykgUFVSRTsKICAgIC8qKiogSUVkaXRTdHJlYW1JbnRlcm5hbCBtZXRob2RzICoqKi8KICAgIFNURE1FVEhPRChHZXRFZGl0U3RyZWFtSW1wbCkoVEhJU18gTFBWT0lEKikgUFVSRTsKfTsKI3VuZGVmIElOVEVSRkFDRQoKI2RlZmluZSBFZGl0U3RyZWFtRW5kKFRoaXMsc3RyZWFtTnIpICgoVGhpcyktPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICsgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzKS0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUVkaXRTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkFkZFJlZihJQVZJRWRpdFN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblJlbGVhc2UoSUFWSUVkaXRTdHJlYW0qaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DdXQoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ29weShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUGFzdGUoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0gcFNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBsU3RhcnQsTE9ORyBsRW5kKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuQ2xvbmUoSUFWSUVkaXRTdHJlYW0qaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBVklTVFJFQU0qcHBSZXN1bHQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5TZXRJbmZvKElBVklFZGl0U3RyZWFtKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpLExPTkcgc2l6ZSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklFZGl0U3RyZWFtVnRibCBpZWRpdHN0cmVhbSA9IHsKICBJQVZJRWRpdFN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklFZGl0U3RyZWFtX2ZuQWRkUmVmLAogIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZSwKICBJQVZJRWRpdFN0cmVhbV9mbkN1dCwKICBJQVZJRWRpdFN0cmVhbV9mbkNvcHksCiAgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZSwKICBJQVZJRWRpdFN0cmVhbV9mbkNsb25lLAogIElBVklFZGl0U3RyZWFtX2ZuU2V0SW5mbwp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgYnVmZmVyc2l6ZSxMT05HKmJ5dGVzcmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnNhbXB3cml0dGVuLExPTkcqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0QVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRWRpdEFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJQVZJU3RyZWFtVnRibCBpZWRpdHN0YXN0ID0gewogIElFZGl0QVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUVkaXRBVklTdHJlYW1fZm5BZGRSZWYsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWxlYXNlLAogIElFZGl0QVZJU3RyZWFtX2ZuQ3JlYXRlLAogIElFZGl0QVZJU3RyZWFtX2ZuSW5mbywKICBJRWRpdEFWSVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUVkaXRBVklTdHJlYW1fZm5SZWFkRm9ybWF0LAogIElFZGl0QVZJU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIElFZGl0QVZJU3RyZWFtX2ZuUmVhZCwKICBJRWRpdEFWSVN0cmVhbV9mbldyaXRlLAogIElFZGl0QVZJU3RyZWFtX2ZuRGVsZXRlLAogIElFZGl0QVZJU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUVkaXRBVklTdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUVkaXRBVklTdHJlYW1fZm5TZXRJbmZvCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVkaXRTdHJlYW1JbnRlcm5hbF9mblF1ZXJ5SW50ZXJmYWNlKElFZGl0U3RyZWFtSW50ZXJuYWwqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5BZGRSZWYoSUVkaXRTdHJlYW1JbnRlcm5hbCppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJRWRpdFN0cmVhbUludGVybmFsX2ZuUmVsZWFzZShJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5HZXRFZGl0U3RyZWFtSW1wbChJRWRpdFN0cmVhbUludGVybmFsKmlmYWNlLExQVk9JRCpwcGltcGwpOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJRWRpdFN0cmVhbUludGVybmFsVnRibCBpZWRpdHN0cmVhbWludGVybmFsID0gewogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5RdWVyeUludGVyZmFjZSwKICBJRWRpdFN0cmVhbUludGVybmFsX2ZuQWRkUmVmLAogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5SZWxlYXNlLAogIElFZGl0U3RyZWFtSW50ZXJuYWxfZm5HZXRFZGl0U3RyZWFtSW1wbAp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklFZGl0U3RyZWFtSW1wbCBJQVZJRWRpdFN0cmVhbUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUVkaXRBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElBVklTdHJlYW1WdGJsICpscFZ0Ymw7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBJQVZJRWRpdFN0cmVhbUltcGwgKnBhZTsKfSBJRWRpdEFWSVN0cmVhbUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUVkaXRTdHJlYW1JbnRlcm5hbFZ0YmwgKmxwVnRibDsKCiAgLyogSUVkaXRTdHJlYW1JbnRlcm5hbCBzdHVmZiAqLwogIElBVklFZGl0U3RyZWFtSW1wbCAqcGFlOwp9IElFZGl0U3RyZWFtSW50ZXJuYWxJbXBsOwoKc3RydWN0IF9JQVZJRWRpdFN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSUVkaXRTdHJlYW1WdGJsICpscFZ0Ymw7CiAgTE9ORyAgcmVmOwoKICAvKiBJQVZJRWRpdFN0cmVhbSBzdHVmZiAqLwogIElFZGl0QVZJU3RyZWFtSW1wbCAgICAgIGlBVklTdHJlYW07CiAgSUVkaXRTdHJlYW1JbnRlcm5hbEltcGwgaUVkaXRTdHJlYW1JbnRlcm5hbDsKCiAgQVZJU1RSRUFNSU5GT1cgICAgICAgc0luZm87CgogIEVkaXRTdHJlYW1UYWJsZSAgICAgKnBTdHJlYW1zOwogIERXT1JEICAgICAgICAgICAgICAgIG5TdHJlYW1zOyAgIC8qIGN1cnJlbnQgZmlsbCBsZXZlbCBvZiBwU3RyZWFtcyB0YWJsZSAqLwogIERXT1JEICAgICAgICAgICAgICAgIG5UYWJsZVNpemU7IC8qIHNpemUgb2YgcFN0cmVhbXMgdGFibGUgKi8KCiAgQk9PTCAgICAgICAgICAgICAgICAgYkRlY29tcHJlc3M7CiAgUEFWSVNUUkVBTSAgICAgICAgICAgcEN1clN0cmVhbTsKICBQR0VURlJBTUUgICAgICAgICAgICBwZzsgICAgICAgICAvKiBJR2V0RnJhbWUgZm9yIHBDdXJTdHJlYW0gKi8KICBMUEJJVE1BUElORk9IRUFERVIgICBscEZyYW1lOyAgICAvKiBmcmFtZSBvZiBwQ3VyU3RyZWFtICovCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpQQVZJRURJVFNUUkVBTSBBVklGSUxFX0NyZWF0ZUVkaXRTdHJlYW0oUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpwZWRpdCA9IE5VTEw7CgogIHBlZGl0ID0gKElBVklFZGl0U3RyZWFtSW1wbCopTG9jYWxBbGxvYyhMUFRSLHNpemVvZihJQVZJRWRpdFN0cmVhbUltcGwpKTsKICBpZiAocGVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICBwZWRpdC0+bHBWdGJsICAgICAgICAgICAgPSAmaWVkaXRzdHJlYW07CiAgcGVkaXQtPmlBVklTdHJlYW0ubHBWdGJsID0gJmllZGl0c3Rhc3Q7CiAgcGVkaXQtPmlBVklTdHJlYW0ucGFlICAgID0gcGVkaXQ7CiAgcGVkaXQtPmlFZGl0U3RyZWFtSW50ZXJuYWwubHBWdGJsID0gJmllZGl0c3RyZWFtaW50ZXJuYWw7CiAgcGVkaXQtPmlFZGl0U3RyZWFtSW50ZXJuYWwucGFlICAgID0gcGVkaXQ7CiAgcGVkaXQtPnJlZiA9IDE7CgogIElBVklTdHJlYW1fQ3JlYXRlKChQQVZJU1RSRUFNKSZwZWRpdC0+aUFWSVN0cmVhbSwoTFBBUkFNKXBzdHJlYW0sMCk7CgogIHJldHVybiAoUEFWSUVESVRTVFJFQU0pcGVkaXQ7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUoSUFWSUVkaXRTdHJlYW1JbXBsKiBjb25zdCBUaGlzLAoJCQkJCSBEV09SRCBwb3MsUEFWSVNUUkVBTSAqcHBTdHJlYW0sCgkJCQkJIERXT1JEKiBzdHJlYW1Qb3MsCgkJCQkJIERXT1JEKiBzdHJlYW1OcixCT09MIGJGaW5kU2FtcGxlKQp7CiAgRFdPUkQgbjsKCiAgVFJBQ0UoIiglcCwlbHUsJXAsJXAsJXAsJWQpXG4iLFRoaXMscG9zLHBwU3RyZWFtLHN0cmVhbVBvcywKICAgICAgICBzdHJlYW1OcixiRmluZFNhbXBsZSk7CgogIGlmIChwb3MgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgcG9zIC09IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgZm9yIChuID0gMDsgbiA8IFRoaXMtPm5TdHJlYW1zOyBuKyspIHsKICAgIGlmIChwb3MgPCBUaGlzLT5wU3RyZWFtc1tuXS5kd0xlbmd0aCkgewogICAgICAqcHBTdHJlYW0gID0gVGhpcy0+cFN0cmVhbXNbbl0ucFN0cmVhbTsKICAgICAgKnN0cmVhbVBvcyA9IFRoaXMtPnBTdHJlYW1zW25dLmR3U3RhcnQgKyBwb3M7CiAgICAgIGlmIChzdHJlYW1OciAhPSBOVUxMKQogICAgICAgICpzdHJlYW1OciA9IG47CgogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgfQogICAgcG9zIC09IFRoaXMtPnBTdHJlYW1zW25dLmR3TGVuZ3RoOwogIH0KICBpZiAocG9zID09IDAgJiYgYkZpbmRTYW1wbGUpIHsKICAgICpwcFN0cmVhbSAgPSBUaGlzLT5wU3RyZWFtc1stLW5dLnBTdHJlYW07CiAgICAqc3RyZWFtUG9zID0gRWRpdFN0cmVhbUVuZChUaGlzLCBuKTsKICAgIGlmIChzdHJlYW1OciAhPSBOVUxMKQogICAgICAqc3RyZWFtTnIgPSBuOwoKICAgIFRSQUNFKCIgLS0gcG9zPTAgJiYgYj0xIC0+ICglcCwlbHUsJWx1KVxuIiwqcHBTdHJlYW0sICpzdHJlYW1Qb3MsIG4pOwogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UgewogICAgKnBwU3RyZWFtID0gTlVMTDsKICAgICpzdHJlYW1Qb3MgPSAwOwogICAgaWYgKHN0cmVhbU5yICE9IE5VTEwpCiAgICAgICpzdHJlYW1OciA9IDA7CgogICAgVFJBQ0UoIiAtPiBFUlJPUiAoTlVMTCwwLDApXG4iKTsKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgfQp9CgpzdGF0aWMgTFBWT0lEIEFWSUZJTEVfUmVhZEZyYW1lKElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zKQp7CiAgUEdFVEZSQU1FIHBnOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsVGhpcyxwc3RyZWFtLHBvcyk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gTlVMTDsKCiAgLyogaWYgc3RyZWFtIGNoYW5nZXMgbWFrZSBzdXJlIHRoYXQgb25seSBwYWxldHRlIGNoYW5nZXMgKi8KICBpZiAoVGhpcy0+cEN1clN0cmVhbSAhPSBwc3RyZWFtKSB7CiAgICBwZyA9IEFWSVN0cmVhbUdldEZyYW1lT3Blbihwc3RyZWFtLCBOVUxMKTsKICAgIGlmIChwZyA9PSBOVUxMKQogICAgICByZXR1cm4gTlVMTDsKICAgIGlmIChUaGlzLT5wZyAhPSBOVUxMKSB7CiAgICAgIGlmIChJR2V0RnJhbWVfU2V0Rm9ybWF0KHBnLCBUaGlzLT5scEZyYW1lLCBOVUxMLCAwLCAwLCAtMSwgLTEpKSB7CiAgICAgICAgQVZJU3RyZWFtR2V0RnJhbWVDbG9zZShwZyk7CiAgICAgICAgRVJSKCI6IElHZXRGcmFtZV9TZXRGb3JtYXQgZmFpbGVkXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgfQogICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKFRoaXMtPnBnKTsKICAgIH0KICAgIFRoaXMtPnBnICAgICAgICAgPSBwZzsKICAgIFRoaXMtPnBDdXJTdHJlYW0gPSBwc3RyZWFtOwogIH0KCiAgLyogbm93IGdldCB0aGUgZGVjb21wcmVzc2VkIGZyYW1lICovCiAgVGhpcy0+bHBGcmFtZSA9IEFWSVN0cmVhbUdldEZyYW1lKFRoaXMtPnBnLCBwb3MpOwogIGlmIChUaGlzLT5scEZyYW1lICE9IE5VTEwpCiAgICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5scEZyYW1lLT5iaVNpemVJbWFnZTsKCiAgcmV0dXJuIFRoaXMtPmxwRnJhbWU7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVtb3ZlU3RyZWFtKElBVklFZGl0U3RyZWFtSW1wbCogY29uc3QgVGhpcywgRFdPUkQgbnIpCnsKICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQobnIgPCBUaGlzLT5uU3RyZWFtcyk7CgogIC8qIHJlbW92ZSBwYXJ0IG5yICovCiAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW1zW25yXS5wU3RyZWFtKTsKICBUaGlzLT5uU3RyZWFtcy0tOwogIGlmIChUaGlzLT5uU3RyZWFtcyAtIG5yID4gMCkgewogICAgbWVtbW92ZShUaGlzLT5wU3RyZWFtcyArIG5yLCBUaGlzLT5wU3RyZWFtcyArIG5yICsgMSwKICAgICAgICAgICAgKFRoaXMtPm5TdHJlYW1zIC0gbnIpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogIH0KICBUaGlzLT5wU3RyZWFtc1tUaGlzLT5uU3RyZWFtc10ucFN0cmVhbSAgPSBOVUxMOwogIFRoaXMtPnBTdHJlYW1zW1RoaXMtPm5TdHJlYW1zXS5kd1N0YXJ0ICA9IDA7CiAgVGhpcy0+cFN0cmVhbXNbVGhpcy0+blN0cmVhbXNdLmR3TGVuZ3RoID0gMDsKCiAgLyogdHJ5IHRvIG1lcmdlIHRoZSBwYXJ0IGJlZm9yZSB0aGUgZGVsZXRlZCBvbmUgYW5kIHRoZSBvbmUgYWZ0ZXIgaXQgKi8KICBpZiAoMCA8IG5yICYmIDAgPCBUaGlzLT5uU3RyZWFtcyAmJgogICAgICBUaGlzLT5wU3RyZWFtc1tuciAtIDFdLnBTdHJlYW0gPT0gVGhpcy0+cFN0cmVhbXNbbnJdLnBTdHJlYW0pIHsKICAgIGlmIChFZGl0U3RyZWFtRW5kKFRoaXMsIG5yIC0gMSkgPT0gVGhpcy0+cFN0cmVhbXNbbnJdLmR3U3RhcnQpIHsKICAgICAgVGhpcy0+cFN0cmVhbXNbbnIgLSAxXS5kd0xlbmd0aCArPSBUaGlzLT5wU3RyZWFtc1tucl0uZHdMZW5ndGg7CiAgICAgIHJldHVybiBBVklGSUxFX1JlbW92ZVN0cmVhbShUaGlzLCBucik7CiAgICB9CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgQk9PTCBBVklGSUxFX0Zvcm1hdHNFcXVhbChQQVZJU1RSRUFNIGF2aTEsIFBBVklTVFJFQU0gYXZpMikKewogIExQVk9JRCBmbXQxID0gTlVMTCwgZm10MiA9IE5VTEw7CiAgTE9ORyBzaXplMSwgc2l6ZTIsIHN0YXJ0MSwgc3RhcnQyOwogIEJPT0wgc3RhdHVzID0gRkFMU0U7CgogIGFzc2VydChhdmkxICE9IE5VTEwgJiYgYXZpMiAhPSBOVUxMKTsKCiAgLyogZ2V0IHN0cmVhbSBzdGFydHMgYW5kIGNoZWNrIGZvcm1hdCBzaXplcyAqLwogIHN0YXJ0MSA9IEFWSVN0cmVhbVN0YXJ0KGF2aTEpOwogIHN0YXJ0MiA9IEFWSVN0cmVhbVN0YXJ0KGF2aTIpOwogIGlmIChGQUlMRUQoQVZJU3RyZWFtRm9ybWF0U2l6ZShhdmkxLCBzdGFydDEsICZzaXplMSkpKQogICAgcmV0dXJuIEZBTFNFOwogIGlmIChGQUlMRUQoQVZJU3RyZWFtRm9ybWF0U2l6ZShhdmkyLCBzdGFydDIsICZzaXplMikpKQogICAgcmV0dXJuIEZBTFNFOwogIGlmIChzaXplMSAhPSBzaXplMikKICAgIHJldHVybiBGQUxTRTsKCiAgLyogc2l6ZXMgbWF0Y2gsIG5vdyBnZXQgZm9ybWF0cyBhbmQgY29tcGFyZSB0aGVtICovCiAgZm10MSA9IEdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemUxKTsKICBpZiAoZm10MSA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwogIGlmIChTVUNDRUVERUQoQVZJU3RyZWFtUmVhZEZvcm1hdChhdmkxLCBzdGFydDEsIGZtdDEsICZzaXplMSkpKSB7CiAgICBmbXQyID0gR2xvYmFsQWxsb2NQdHIoR0hORCwgc2l6ZTEpOwogICAgaWYgKGZtdDIgIT0gTlVMTCkgewogICAgICBpZiAoU1VDQ0VFREVEKEFWSVN0cmVhbVJlYWRGb3JtYXQoYXZpMiwgc3RhcnQyLCBmbXQyLCAmc2l6ZTEpKSkKICAgICAgICBzdGF0dXMgPSAobWVtY21wKGZtdDEsIGZtdDIsIHNpemUxKSA9PSAwKTsKICAgIH0KICB9CgogIGlmIChmbXQyICE9IE5VTEwpCiAgICBHbG9iYWxGcmVlUHRyKGZtdDIpOwogIEdsb2JhbEZyZWVQdHIoZm10MSk7CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklFZGl0U3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSUVkaXRTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSBpZmFjZTsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUFWSVN0cmVhbTsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lFZGl0U3RyZWFtSW50ZXJuYWwsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUVkaXRTdHJlYW1JbnRlcm5hbDsKICAgIElBVklFZGl0U3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRWRpdFN0cmVhbV9mbkFkZFJlZihJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklFZGl0U3RyZWFtX2ZuUmVsZWFzZShJQVZJRWRpdFN0cmVhbSppZmFjZSkKewogIElBVklFZGl0U3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJRWRpdFN0cmVhbUltcGwgKilpZmFjZTsKICBEV09SRCBpOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAoIXJlZikgewogICAgLyogcmVsZWFzZSBtZW1vcnkgKi8KICAgIGlmIChUaGlzLT5wZyAhPSBOVUxMKQogICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKFRoaXMtPnBnKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtcyAhPSBOVUxMKSB7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5uU3RyZWFtczsgaSsrKSB7CiAgICAgICAgaWYgKFRoaXMtPnBTdHJlYW1zW2ldLnBTdHJlYW0gIT0gTlVMTCkKICAgICAgICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtc1tpXS5wU3RyZWFtKTsKICAgICAgfQogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPnBTdHJlYW1zKTsKICAgIH0KCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5DdXQoSUFWSUVkaXRTdHJlYW0qaWZhY2UsTE9ORypwbFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORypwbExlbmd0aCxQQVZJU1RSRUFNKnBwUmVzdWx0KQp7CiAgSUFWSUVkaXRTdHJlYW1JbXBsICpUaGlzID0gKElBVklFZGl0U3RyZWFtSW1wbCAqKWlmYWNlOwogIFBBVklTVFJFQU0gc3RyZWFtOwogIERXT1JEICAgICAgc3RhcnQsIGxlbiwgc3RyZWFtUG9zLCBzdHJlYW1OcjsKICBIUkVTVUxUICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ICE9IE5VTEwpCiAgICAqcHBSZXN1bHQgPSBOVUxMOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCAqcGxTdGFydCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBpZiBhc2tlZCBmb3IgY3V0dGVkIHBhcnQgY29weSBpdCBiZWZvcmUgZGVsZXRpbmcgKi8KICBpZiAocHBSZXN1bHQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9Db3B5KGlmYWNlLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIHN0YXJ0ID0gKnBsU3RhcnQ7CiAgbGVuICAgPSAqcGxMZW5ndGg7CgogIC8qIG5vdyBkZWxldGUgdGhlIHJlcXVlc3RlZCBwYXJ0ICovCiAgd2hpbGUgKGxlbiA+IDApIHsKICAgIGhyID0gQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShUaGlzLCBzdGFydCwgJnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RyZWFtUG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgICBpZiAoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3U3RhcnQgPT0gc3RyZWFtUG9zKSB7CiAgICAgIC8qIGRlbGV0aW5nIGZyb20gc3RhcnQgb2YgcGFydCAqLwogICAgICBpZiAobGVuIDwgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoKSB7CiAgICAgICAgc3RhcnQgKz0gbGVuOwogICAgICAgIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0ICArPSBsZW47CiAgICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnJdLmR3TGVuZ3RoIC09IGxlbjsKICAgICAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBsZW47CiAgICAgICAgbGVuID0gMDsKCiAgICAgICAgLyogd2UgbXVzdCByZXR1cm4gZGVjb21wcmVzc2VkIGRhdGEgbm93ICovCiAgICAgICAgVGhpcy0+YkRlY29tcHJlc3MgPSBUUlVFOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIGRlbGV0aW5nIGhvbGUgcGFydCAqLwogICAgICAgIGxlbiAtPSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CiAgICAgICAgQVZJRklMRV9SZW1vdmVTdHJlYW0oVGhpcyxzdHJlYW1Ocik7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgPD0gc3RyZWFtUG9zICsgbGVuKSB7CiAgICAgIC8qIGRlbGV0aW5nIGF0IGVuZCBvZiBhIHBhcnQgKi8KICAgICAgRFdPUkQgY291bnQgPSBFZGl0U3RyZWFtRW5kKFRoaXMsIHN0cmVhbU5yKSAtIHN0cmVhbVBvczsKICAgICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gY291bnQ7CiAgICAgIGxlbiAgICAgICAgICAgICAgICAgIC09IGNvdW50OwogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQogICAgICAgIHN0cmVhbVBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgfSBlbHNlIHsKICAgICAgLyogc3BsaXR0aW5nICovCiAgICAgIGlmIChUaGlzLT5uU3RyZWFtcyArIDEgPj0gVGhpcy0+blRhYmxlU2l6ZSkgewogICAgICAgIFRoaXMtPnBTdHJlYW1zID0KICAgICAgICAgIEdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+cFN0cmVhbXMsIChUaGlzLT5uVGFibGVTaXplICsgMzIpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSksIEdNRU1fU0hBUkV8R0hORCk7CiAgICAgICAgaWYgKFRoaXMtPnBTdHJlYW1zID09IE5VTEwpCiAgICAgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgICBUaGlzLT5uVGFibGVTaXplICs9IDMyOwogICAgICB9CiAgICAgIG1lbW1vdmUoVGhpcy0+cFN0cmVhbXMgKyBzdHJlYW1OciArIDEsIFRoaXMtPnBTdHJlYW1zICsgc3RyZWFtTnIsCiAgICAgICAgICAgICAgKFRoaXMtPm5TdHJlYW1zIC0gc3RyZWFtTnIpICogc2l6ZW9mKEVkaXRTdHJlYW1UYWJsZSkpOwogICAgICBUaGlzLT5uU3RyZWFtcysrOwoKICAgICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5wU3RyZWFtKTsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5kd1N0YXJ0ICA9IHN0cmVhbVBvcyArIGxlbjsKICAgICAgVGhpcy0+cFN0cmVhbXNbc3RyZWFtTnIgKyAxXS5kd0xlbmd0aCA9CiAgICAgICAgRWRpdFN0cmVhbUVuZChUaGlzLCBzdHJlYW1OcikgLSBUaGlzLT5wU3RyZWFtc1tzdHJlYW1OciArIDFdLmR3U3RhcnQ7CgogICAgICBUaGlzLT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGggPQogICAgICAgIHN0cmVhbVBvcyAtIFRoaXMtPnBTdHJlYW1zW3N0cmVhbU5yXS5kd1N0YXJ0OwogICAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBsZW47CiAgICAgIGxlbiA9IDA7CiAgICB9CiAgfQoKICBUaGlzLT5zSW5mby5kd0VkaXRDb3VudCsrOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5Db3B5KElBVklFZGl0U3RyZWFtKmlmYWNlLExPTkcqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HKnBsTGVuZ3RoLFBBVklTVFJFQU0qcHBSZXN1bHQpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgSUFWSUVkaXRTdHJlYW1JbXBsKiBwRWRpdDsKICBIUkVTVUxUIGhyOwogIExPTkcgc3RhcnQgPSAwOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIixpZmFjZSxwbFN0YXJ0LHBsTGVuZ3RoLHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogICpwcFJlc3VsdCA9IE5VTEw7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8ICpwbFN0YXJ0IDwgMCB8fCAqcGxMZW5ndGggPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY2hlY2sgYm91bmRzICovCiAgaWYgKCooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgKihMUERXT1JEKXBsTGVuZ3RoID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKCooTFBEV09SRClwbFN0YXJ0IDwgVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgKihMUERXT1JEKXBsTGVuZ3RoIC09IFRoaXMtPnNJbmZvLmR3U3RhcnQgLSAqKExQRFdPUkQpcGxTdGFydDsKICAgICooTFBEV09SRClwbFN0YXJ0ICAgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgaWYgKCpwbExlbmd0aCA8IDApCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgfQogIGlmICgqKExQRFdPUkQpcGxTdGFydCArICooTFBEV09SRClwbExlbmd0aCA+IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgICooTFBEV09SRClwbExlbmd0aCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCAtCiAgICAgICooTFBEV09SRClwbFN0YXJ0OwoKICBwRWRpdCA9IChJQVZJRWRpdFN0cmVhbUltcGwqKUFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShOVUxMKTsKICBpZiAocEVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IElBVklFZGl0U3RyZWFtX1Bhc3RlKChQQVZJRURJVFNUUkVBTSlwRWRpdCwmc3RhcnQscGxMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwqcGxTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICpwbFN0YXJ0ICsgKnBsTGVuZ3RoKTsKICAqcGxTdGFydCA9IHN0YXJ0OwogIGlmIChGQUlMRUQoaHIpKQogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZSgoUEFWSUVESVRTVFJFQU0pcEVkaXQpOwogIGVsc2UKICAgICpwcFJlc3VsdCA9IChQQVZJU1RSRUFNKSZwRWRpdC0+aUFWSVN0cmVhbTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUVkaXRTdHJlYW1fZm5QYXN0ZShJQVZJRWRpdFN0cmVhbSppZmFjZSxMT05HKnBsU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcqcGxMZW5ndGgsUEFWSVNUUkVBTSBwU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIGxTdGFydCxMT05HIGxMZW5ndGgpCnsKICBJQVZJRWRpdFN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSUVkaXRTdHJlYW1JbXBsICopaWZhY2U7CiAgQVZJU1RSRUFNSU5GT1cgICAgICBzcmNJbmZvOwogIElFZGl0U3RyZWFtSW50ZXJuYWwqcEludGVybmFsID0gTlVMTDsKICBJQVZJRWRpdFN0cmVhbUltcGwgKnBFZGl0ID0gTlVMTDsKICBQQVZJU1RSRUFNICAgICAgICAgIHBTdHJlYW07CiAgRFdPUkQgICAgICAgICAgICAgICBzdGFydFBvcywgZW5kUG9zLCBzdHJlYW1OciwgblN0cmVhbXM7CiAgVUxPTkcgICAgICAgICAgICAgICBuOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVsZCwlbGQpXG4iLGlmYWNlLHBsU3RhcnQscGxMZW5ndGgsCglwU291cmNlLGxTdGFydCxsTGVuZ3RoKTsKCiAgaWYgKHBTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgKnBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKnBsU3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOyAvKiBDYW4ndCBwYXN0ZSB3aXRoIGhvbGVzICovCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocFNvdXJjZSwgJnNyY0luZm8sIHNpemVvZihzcmNJbmZvKSkpKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICBpZiAobFN0YXJ0IDwgc3JjSW5mby5kd1N0YXJ0IHx8IGxTdGFydCA+PSBzcmNJbmZvLmR3U3RhcnQgKyBzcmNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSAwKSB7CiAgICAvKiBUaGlzIHN0cmVhbSBpcyBlbXB0eSAqLwogICAgSUFWSVN0cmVhbV9JbmZvKHBTb3VyY2UsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ICA9ICpwbFN0YXJ0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSAwOwogIH0KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzcmNJbmZvLmZjY1R5cGUpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBkaWZmZXJlbnQgc3RyZWFtIHR5cGVzICovCiAgaWYgKGxMZW5ndGggPT0gLTEpIC8qIENvcHkgdGhlIGhvbGUgc3RyZWFtICovCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd0xlbmd0aDsKICBpZiAobFN0YXJ0ICsgbExlbmd0aCA+IHNyY0luZm8uZHdTdGFydCArIHNyY0luZm8uZHdMZW5ndGgpCiAgICBsTGVuZ3RoID0gc3JjSW5mby5kd1N0YXJ0ICsgc3JjSW5mby5kd0xlbmd0aCAtIGxTdGFydDsKICBpZiAobExlbmd0aCArICpwbFN0YXJ0ID49IDB4ODAwMDAwMDApCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogc3RyZWFtdHlwZSBzcGVjaWZpYyB0ZXN0cyAqLwogIGlmIChzcmNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICBMT05HIHNpemU7CgogICAgc2l6ZSA9IHNyY0luZm8ucmNGcmFtZS5yaWdodCAtIHNyY0luZm8ucmNGcmFtZS5sZWZ0OwogICAgaWYgKHNpemUgIT0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogRklYTUU6IENhbid0IEdldEZyYW1lIGNvbnZlcnQgaXQ/ICovCiAgICBzaXplID0gc3JjSW5mby5yY0ZyYW1lLmJvdHRvbSAtIHNyY0luZm8ucmNGcmFtZS50b3A7CiAgICBpZiAoc2l6ZSAhPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBGSVhNRTogQ2FuJ3QgR2V0RnJhbWUgY29udmVydCBpdD8gKi8KICB9IGVsc2UgaWYgKHNyY0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKICAgIGlmICghIEFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UgewogICAgLyogRklYTUU6IHN0cmVhbXR5cGVNSURJIGFuZCBzdHJlYW10eXBlVEVYVCAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIHRyeSB0byBnZXQgYW4gSUVkaXRTdHJlYW1JbnRlcm5hbCBpbnRlcmZhY2UgKi8KICBpZiAoU1VDQ0VFREVEKElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFNvdXJjZSwgJklJRF9JRWRpdFN0cmVhbUludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKikmcEludGVybmFsKSkpIHsKICAgIHBJbnRlcm5hbC0+bHBWdGJsLT5HZXRFZGl0U3RyZWFtSW1wbChwSW50ZXJuYWwsIChMUFZPSUQqKSZwRWRpdCk7CiAgICBwSW50ZXJuYWwtPmxwVnRibC0+UmVsZWFzZShwSW50ZXJuYWwpOwogIH0KCiAgLyogZm9yIHZpZGVvIG11c3QgY2hlY2sgZm9yIGNoYW5nZSBvZiBmb3JtYXQgKi8KICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgIGlmICghIFRoaXMtPmJEZWNvbXByZXNzKSB7CiAgICAgIC8qIE5lZWQgdG8gZGVjb21wcmVzcyBpZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG1hdGNoZXM6CiAgICAgICAqICAtIHBTb3VyY2UgaXMgYW4gZWRpdGFibGUgc3RyZWFtIHdoaWNoIGRlY29tcHJlc3NlcwogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiBwU291cmNlIGlzbid0IGxTdGFydAogICAgICAgKiAgLSB0aGUgbmVhcmVzdCBrZXlmcmFtZSBvZiB0aGlzIHN0cmVhbSBpc24ndCAqcGxTdGFydAogICAgICAgKiAgLSB0aGUgZm9ybWF0IG9mIHBTb3VyY2UgZG9lc24ndCBtYXRjaCB0aGlzIG9uZQogICAgICAgKi8KICAgICAgaWYgKChwRWRpdCAhPSBOVUxMICYmIHBFZGl0LT5iRGVjb21wcmVzcykgfHwKCSAgQVZJU3RyZWFtTmVhcmVzdEtleUZyYW1lKHBTb3VyY2UsIGxTdGFydCkgIT0gbFN0YXJ0IHx8CgkgIEFWSVN0cmVhbU5lYXJlc3RLZXlGcmFtZSgoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbSwgKnBsU3RhcnQpICE9ICpwbFN0YXJ0IHx8CgkgIChUaGlzLT5uU3RyZWFtcyA+IDAgJiYgIUFWSUZJTEVfRm9ybWF0c0VxdWFsKChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtLCBwU291cmNlKSkpIHsKCS8qIFVzZSBmaXJzdCBzdHJlYW0gcGFydCB0byBnZXQgZm9ybWF0IHRvIGNvbnZlcnQgZXZlcnl0aGluZyB0byAqLwoJQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgVGhpcy0+cFN0cmVhbXNbMF0ucFN0cmVhbSwKCQkJICBUaGlzLT5wU3RyZWFtc1swXS5kd1N0YXJ0KTsKCgkvKiBDaGVjayBpZiB3ZSBjb3VsZCBjb252ZXJ0IHRoZSBzb3VyY2Ugc3RyZWFtcyB0byB0aGUgZGlzaXJlZCBmb3JtYXQuLi4gKi8KCWlmIChwRWRpdCAhPSBOVUxMKSB7CgkgIGlmIChGQUlMRUQoQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJCQkgICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIFRSVUUpKSkKCSAgICByZXR1cm4gQVZJRVJSX0lOVEVSTkFMOwoJICBmb3IgKG4gPSBsU3RhcnQ7IG4gPCBsU3RhcnQgKyBsTGVuZ3RoOyBzdHJlYW1OcisrKSB7CgkgICAgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0ucFN0cmVhbSwgc3RhcnRQb3MpID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCSAgICBzdGFydFBvcyA9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdTdGFydDsKCSAgICBuICs9IHBFZGl0LT5wU3RyZWFtc1tzdHJlYW1Ocl0uZHdMZW5ndGg7CgkgIH0KCX0gZWxzZSBpZiAoQVZJRklMRV9SZWFkRnJhbWUoVGhpcywgcFNvdXJjZSwgbFN0YXJ0KSA9PSBOVUxMKQoJICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCglUaGlzLT5iRGVjb21wcmVzcyAgICAgID0gVFJVRTsKCVRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgPSAwOwogICAgICB9CiAgICB9IGVsc2UgaWYgKEFWSUZJTEVfUmVhZEZyYW1lKFRoaXMsIHBTb3VyY2UsIGxTdGFydCkgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7IC8qIENhbid0IGNvbnZlcnQgc291cmNlIHRvIG93biBmb3JtYXQgKi8KICB9IC8qIEZJWE1FOiBzb21ldGhpbmcgc3BlY2lhbCBmb3IgdGhlIG90aGVyIGZvcm1hdHM/ICovCgogIC8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGVub3VnaCBtZW1vcnkgZm9yIHBhcnRzICovCiAgaWYgKHBFZGl0ICE9IE5VTEwpIHsKICAgIERXT1JEIG5MYXN0U3RyZWFtOwoKICAgIEFWSUZJTEVfRmluZFN0cmVhbUluVGFibGUocEVkaXQsIGxTdGFydCArIGxMZW5ndGgsICZwU3RyZWFtLAoJCQkgICAgICAmZW5kUG9zLCAmbkxhc3RTdHJlYW0sIFRSVUUpOwogICAgQVZJRklMRV9GaW5kU3RyZWFtSW5UYWJsZShwRWRpdCwgbFN0YXJ0LCAmcFN0cmVhbSwKCQkJICAgICAgJnN0YXJ0UG9zLCAmc3RyZWFtTnIsIEZBTFNFKTsKICAgIGlmIChuTGFzdFN0cmVhbSA9PSBzdHJlYW1OcikKICAgICAgbkxhc3RTdHJlYW0rKzsKCiAgICBuU3RyZWFtcyA9IG5MYXN0U3RyZWFtIC0gc3RyZWFtTnI7CiAgfSBlbHNlIAogICAgblN0cmVhbXMgPSAxOwogIGlmIChUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMSA+IFRoaXMtPm5UYWJsZVNpemUpIHsKICAgIG4gPSBUaGlzLT5uU3RyZWFtcyArIG5TdHJlYW1zICsgMzM7CgogICAgVGhpcy0+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=