LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgojaW5jbHVkZSAiZXh0cmFjaHVuay5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIGZvcm10eXBlV0FWRSAgICBtbWlvRk9VUkNDKCdXJywnQScsJ1YnLCdFJykKI2RlZmluZSBja2lkV0FWRUZPUk1BVCAgbW1pb0ZPVVJDQygnZicsJ20nLCd0JywnICcpCiNkZWZpbmUgY2tpZFdBVkVGQUNUICAgIG1taW9GT1VSQ0MoJ2YnLCdhJywnYycsJ3QnKQojZGVmaW5lIGNraWRXQVZFREFUQSAgICBtbWlvRk9VUkNDKCdkJywnYScsJ3QnLCdhJykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgRU5ESUFOX1NXQVBXT1JEKHgpICAoKCgoeCkgPj4gOCkgJiAweEZGKSB8ICgoKHgpICYgMHhGRikgPDwgOCkpCiNkZWZpbmUgRU5ESUFOX1NXQVBEV09SRCh4KSAoRU5ESUFOX1NXQVBXT1JEKCh4ID4+IDE2KSAmIDB4RkZGRikgfCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRU5ESUFOX1NXQVBXT1JEKHggJiAweEZGRkYpIDw8IDE2KQoKI2lmZGVmIFdPUkRTX0JJR0VORElBTgojZGVmaW5lIEJFMkhfV09SRCh4KSAgKHgpCiNkZWZpbmUgQkUySF9EV09SRCh4KSAoeCkKI2RlZmluZSBMRTJIX1dPUkQoeCkgIEVORElBTl9TV0FQV09SRCh4KQojZGVmaW5lIExFMkhfRFdPUkQoeCkgRU5ESUFOX1NXQVBEV09SRCh4KQojZWxzZQojZGVmaW5lIEJFMkhfV09SRCh4KSAgRU5ESUFOX1NXQVBXT1JEKHgpCiNkZWZpbmUgQkUySF9EV09SRCh4KSBFTkRJQU5fU1dBUERXT1JEKHgpCiNkZWZpbmUgTEUySF9XT1JEKHgpICAoeCkKI2RlZmluZSBMRTJIX0RXT1JEKHgpICh4KQojZW5kaWYKCnR5cGVkZWYgc3RydWN0IHsKICBGT1VSQ0MgIGZjY1R5cGU7CiAgRFdPUkQgICBvZmZzZXQ7CiAgRFdPUkQgICBzaXplOwogIElOVCAgICAgZW5jb2Rpbmc7CiAgRFdPUkQgICBzYW1wbGVSYXRlOwogIERXT1JEICAgY2hhbm5lbHM7Cn0gU1VOQVVESU9IRUFERVI7CgojZGVmaW5lIEFVX0VOQ09ESU5HX1VMQVdfOCAgICAgICAgICAgICAgICAgMQojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV84ICAgICAgICAgICAgICAgICAgMgojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8xNiAgICAgICAgICAgICAgICAgMwojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8yNCAgICAgICAgICAgICAgICAgNAojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8zMiAgICAgICAgICAgICAgICAgNQojZGVmaW5lIEFVX0VOQ09ESU5HX0ZMT0FUICAgICAgICAgICAgICAgICAgNgojZGVmaW5lIEFVX0VOQ09ESU5HX0RPVUJMRSAgICAgICAgICAgICAgICAgNwojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzIgICAgICAgICAyMwojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjIgICAgICAgICAgICAyNAojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQgICAgICAgICAyNQojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfNSAgICAgICAgICAyNgojZGVmaW5lIEFVX0VOQ09ESU5HX0FMQVdfOCAgICAgICAgICAgICAgICAyNwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUqIGlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlKmlmYWNlLEFWSUZJTEVJTkZPVyphZmksTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuR2V0U3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxBVklTVFJFQU1JTkZPVyphc2kpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HICpzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRW5kUmVjb3JkKElBVklGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwoKc3RydWN0IElBVklGaWxlVnRibCBpd2F2ZnQgPSB7CiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdHJ1Y3QgSVBlcnNpc3RGaWxlVnRibCBpd2F2cGZ0ID0gewogIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElQZXJzaXN0RmlsZV9mbkFkZFJlZiwKICBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlLAogIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQsCiAgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eSwKICBJUGVyc2lzdEZpbGVfZm5Mb2FkLAogIElQZXJzaXN0RmlsZV9mblNhdmUsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZCwKICBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLExPTkcgKmJ5dGVzcmVhZCxMT05HICpzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0cnVjdCBJQVZJU3RyZWFtVnRibCBpd2F2c3QgPSB7CiAgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklTdHJlYW1fZm5BZGRSZWYsCiAgSUFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUFWSVN0cmVhbV9mbkNyZWF0ZSwKICBJQVZJU3RyZWFtX2ZuSW5mbywKICBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIElBVklTdHJlYW1fZm5SZWFkLAogIElBVklTdHJlYW1fZm5Xcml0ZSwKICBJQVZJU3RyZWFtX2ZuRGVsZXRlLAogIElBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhLAogIElBVklTdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSUZpbGVJbXBsIElBVklGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JUGVyc2lzdEZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElQZXJzaXN0RmlsZVZ0YmwgKmxwVnRibDsKCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElQZXJzaXN0RmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUFWSVN0cmVhbVZ0YmwgICAqbHBWdGJsOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElBVklTdHJlYW1JbXBsOwoKc3RydWN0IF9JQVZJRmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUFWSUZpbGVWdGJsICAgICAqbHBWdGJsOwogIERXT1JECQkgICAgcmVmOwoKICAvKiBJQVZJRmlsZSwgSUFWSVN0cmVhbSBzdHVmZi4uLiAqLwogIElQZXJzaXN0RmlsZUltcGwgIGlQZXJzaXN0RmlsZTsKICBJQVZJU3RyZWFtSW1wbCAgICBpQVZJU3RyZWFtOwoKICBBVklGSUxFSU5GT1cgICAgICBmSW5mbzsKICBBVklTVFJFQU1JTkZPVyAgICBzSW5mbzsKCiAgTFBXQVZFRk9STUFURVggICAgbHBGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgICAgY2JGb3JtYXQ7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrRGF0YTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZXh0cmE7CgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAuLi4gKi8KICBITU1JTyAgICAgICAgICAgICBobW1pbzsKICBMUFdTVFIgICAgICAgICAgICBzekZpbGVOYW1lOwogIFVJTlQgICAgICAgICAgICAgIHVNb2RlOwogIEJPT0wgICAgICAgICAgICAgIGZEaXJ0eTsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkU3VuRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlV0FWRmlsZShSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICBJQVZJRmlsZUltcGwgKnBmaWxlOwogIEhSRVNVTFQgICAgICAgaHI7CgogIGFzc2VydChyaWlkICE9IE5VTEwgJiYgcHB2ICE9IE5VTEwpOwoKICAqcHB2ID0gTlVMTDsKCiAgcGZpbGUgPSAoSUFWSUZpbGVJbXBsKilMb2NhbEFsbG9jKExQVFIsIHNpemVvZihJQVZJRmlsZUltcGwpKTsKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwZmlsZS0+bHBWdGJsICAgICAgICAgICAgICAgID0gJml3YXZmdDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLmxwVnRibCAgID0gJml3YXZwZnQ7CiAgcGZpbGUtPmlBVklTdHJlYW0ubHBWdGJsICAgICA9ICZpd2F2c3Q7CiAgcGZpbGUtPnJlZiA9IDA7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5wYWYgPSBwZmlsZTsKICBwZmlsZS0+aUFWSVN0cmVhbS5wYWYgICA9IHBmaWxlOwoKICBociA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKChJVW5rbm93biopcGZpbGUsIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBMb2NhbEZyZWUoKEhMT0NBTClwZmlsZSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUgKmlmYWNlLCBSRUZJSUQgcmVmaWlkLAoJCQkJCQlMUFZPSUQgKm9iaikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgPT0gMSAmJgoJICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUFWSVN0cmVhbTsKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUGVyc2lzdEZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aVBlcnNpc3RGaWxlOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIHJldHVybiArKyhUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgaWYgKCEtLShUaGlzLT5yZWYpKSB7CiAgICBpZiAoVGhpcy0+ZkRpcnR5KSB7CiAgICAgIC8qIG5lZWQgdG8gd3JpdGUgaGVhZGVycyB0byBmaWxlICovCiAgICAgIEFWSUZJTEVfU2F2ZUZpbGUoVGhpcyk7CiAgICB9CgogICAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scEZvcm1hdCk7CiAgICAgIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JGb3JtYXQgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPmV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5leHRyYS5scCk7CiAgICAgIFRoaXMtPmV4dHJhLmxwID0gTlVMTDsKICAgICAgVGhpcy0+ZXh0cmEuY2IgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzLT5zekZpbGVOYW1lKTsKICAgICAgVGhpcy0+c3pGaWxlTmFtZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkgewogICAgICBtbWlvQ2xvc2UoVGhpcy0+aG1taW8sIDApOwogICAgICBUaGlzLT5obW1pbyA9IE5VTEw7CiAgICB9CgogICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcyk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIFRoaXMtPnJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSAqaWZhY2UsIExQQVZJRklMRUlORk9XIGFmaSwKCQkJCSAgICAgIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLGlmYWNlLGFmaSxzaXplKTsKCiAgaWYgKGFmaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIHVwZGF0ZSBmaWxlIGluZm8gKi8KICBUaGlzLT5mSW5mby5kd0ZsYWdzID0gMDsKICBUaGlzLT5mSW5mby5kd0NhcHMgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U2NhbGUgIT0gMCk7CgogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICAgICAgICAgICAgID0gMTsKICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3U2NhbGU7CiAgICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBUaGlzLT5zSW5mby5kd1JhdGU7CiAgICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICAgIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjID0KICAgICAgTXVsRGl2KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSxUaGlzLT5zSW5mby5kd1JhdGUsVGhpcy0+c0luZm8uZHdTY2FsZSk7CiAgfQoKICBtZW1jcHkoYWZpLCAmVGhpcy0+ZkluZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+ZkluZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4bFgsJWxkKVxuIiwgaWZhY2UsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChhdmlzID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqYXZpcyA9IE5VTEw7CgogIC8qIERvZXMgb3VyIHN0cmVhbSBleGlzdHM/ICovCiAgaWYgKGxQYXJhbSAhPSAwIHx8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CiAgaWYgKGZjY1R5cGUgIT0gMCAmJiBmY2NUeXBlICE9IHN0cmVhbXR5cGVBVURJTykKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwoKICAqYXZpcyA9IChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtOwogIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsUEFWSVNUUkVBTSAqYXZpcywKCQkJCQkgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCBhdmlzLCBhc2kpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBhc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogV2Ugb25seSBzdXBwb3J0IG9uZSBhdWRpbyBzdHJlYW0gKi8KICBpZiAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zICE9IDAgfHwgVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgaWYgKGFzaS0+ZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5jYkZvcm1hdCA9IDA7CiAgVGhpcy0+bHBGb3JtYXQgPSBOVUxMOwoKICBtZW1jcHkoJlRoaXMtPnNJbmZvLCBhc2ksIHNpemVvZihUaGlzLT5zSW5mbykpOwoKICAvKiBtYWtlIHN1cmUgc3RyZWFtaW5mbyBpZiBva2F5IGZvciB1cyAqLwogIFRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3RmxhZ3MgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3Q2FwcyAgICAgICAgICAgICAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIFRoaXMtPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgPSAwOwogIG1lbXNldCgmVGhpcy0+c0luZm8ucmNGcmFtZSwgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvLnJjRnJhbWUpKTsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID0gMTsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgPSBUaGlzLT5zSW5mby5kd1NjYWxlOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICA9IFRoaXMtPnNJbmZvLmR3UmF0ZTsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKCiAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IDA7CiAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IDA7CgogICphdmlzID0gKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW07CiAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgICBMUFZPSUQgbHBEYXRhLCBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlbGQpXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscERhdGEgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgcmV0dXJuIFdyaXRlRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgIExQVk9JRCBscERhdGEsIExPTkcgKnNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUgKmlmYWNlKQp7CiAgVFJBQ0UoIiglcClcbiIsaWZhY2UpOwoKICAvKiBUaGlzIGlzIG9ubHkgbmVlZGVkIGZvciBpbnRlcmxlYXZlZCBmaWxlcy4KICAgKiBXZSBoYXZlIG9ubHkgb25lIHN0cmVhbSwgd2hpY2ggY2FuJ3QgYmUgaW50ZXJsZWF2ZWQuCiAgICovCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlICppZmFjZSwgRFdPUkQgZmNjVHlwZSwKCQkJCQkgICAgICBMT05HIGxQYXJhbSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVsZClcbiIsIGlmYWNlLCBmY2NUeXBlLCBsUGFyYW0pOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgKi8KICBpZiAobFBhcmFtIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgd2Ugb3VyIGF1ZGlvIHN0cmVhbT8gKi8KICBpZiAobFBhcmFtICE9IDAgfHwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID09IDAgfHwKICAgICAgKGZjY1R5cGUgIT0gMCAmJiBmY2NUeXBlICE9IHN0cmVhbXR5cGVBVURJTykpCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKCiAgLyogSGF2ZSB1c2VyIHdyaXRlIHBlcm1pc3Npb25zPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBGb3JtYXQpOwogIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKICBUaGlzLT5jYkZvcm1hdCA9IDA7CgogIC8qIHVwZGF0ZSBpbmZvcyAqLwogIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSAwOwogIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSAwOwoKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggID0gMDsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAwOwogIFRoaXMtPmZJbmZvLmR3RWRpdENvdW50Kys7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBtZW1jcHkocENsYXNzSUQsICZDTFNJRF9XQVZGaWxlLCBzaXplb2YoQ0xTSURfV0FWRmlsZSkpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSVBlcnNpc3RGaWxlSW1wbCopaWZhY2UpLT5wYWY7CgogIFdDSEFSIHdzelN0cmVhbUZtdFs1MF07CiAgSU5UICAgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4bFgpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGR3TW9kZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgaWYgKFRoaXMtPmhtbWlvICE9IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBObyByZXVzZSBvZiB0aGlzIG9iamVjdCBmb3IgYW5vdGhlciBmaWxlISAqLwoKICAvKiByZW1lYmVyIG1vZGUgYW5kIG5hbWUgKi8KICBUaGlzLT51TW9kZSA9IGR3TW9kZTsKCiAgbGVuID0gbHN0cmxlblcocHN6RmlsZU5hbWUpICsgMTsKICBUaGlzLT5zekZpbGVOYW1lID0gTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAoVGhpcy0+c3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgbHN0cmNweVcoVGhpcy0+c3pGaWxlTmFtZSwgcHN6RmlsZU5hbWUpOwoKICAvKiB0cnkgdG8gb3BlbiB0aGUgZmlsZSAqLwogIFRoaXMtPmhtbWlvID0gbW1pb09wZW5XKFRoaXMtPnN6RmlsZU5hbWUsIE5VTEwsIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogIGlmIChUaGlzLT5obW1pbyA9PSBOVUxMKSB7CiAgICAvKiBtbWlvT3Blblcgbm90IGluIG5hdGl2ZSBETExzIG9mIFdpbjl4IC0tIHRyeSBtbWlvT3BlbkEgKi8KICAgIExQU1RSIHN6RmlsZU5hbWU7CiAgICBsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgVGhpcy0+c3pGaWxlTmFtZSwgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogICAgc3pGaWxlTmFtZSA9IExvY2FsQWxsb2MoTFBUUiwgbGVuICogc2l6ZW9mKENIQVIpKTsKICAgIGlmIChzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5zekZpbGVOYW1lLCAtMSwgc3pGaWxlTmFtZSwKCQkJbGVuLCBOVUxMLCBOVUxMKTsKCiAgICBUaGlzLT5obW1pbyA9IG1taW9PcGVuQShzekZpbGVOYW1lLCBOVUxMLCBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICAgIExvY2FsRnJlZSgoSExPQ0FMKXN6RmlsZU5hbWUpOwogICAgaWYgKFRoaXMtPmhtbWlvID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfRklMRU9QRU47CiAgfQoKICBtZW1zZXQoJiBUaGlzLT5mSW5mbywgMCwgc2l6ZW9mKFRoaXMtPmZJbmZvKSk7CiAgbWVtc2V0KCYgVGhpcy0+c0luZm8sIDAsIHNpemVvZihUaGlzLT5zSW5mbykpOwoKICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19XQVZFRklMRVRZUEUsIFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUsCgkgICAgICBzaXplb2YoVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSkpOwogIGlmIChMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19XQVZFU1RSRUFNRk9STUFULAoJCSAgd3N6U3RyZWFtRm10LCBzaXplb2Yod3N6U3RyZWFtRm10KSkgPiAwKSB7CiAgICB3c3ByaW50ZlcoVGhpcy0+c0luZm8uc3pOYW1lLCB3c3pTdHJlYW1GbXQsCgkgICAgICBBVklGSUxFX0Jhc2VuYW1lVyhUaGlzLT5zekZpbGVOYW1lKSk7CiAgfQoKICAvKiBzaG91bGQgd2UgY3JlYXRlIGEgbmV3IGZpbGU/ICovCiAgaWYgKGR3TW9kZSAmIE9GX0NSRUFURSkgewogICAgLyogbm90aGluZyBtb3JlIHRvIGRvICovCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUZJTEVfTG9hZEZpbGUoVGhpcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpCnsKICBUUkFDRSgiKCVwLCVzLCVkKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBmUmVtZW1iZXIpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICBMUENPTEVTVFIgcHN6RmlsZU5hbWUpCnsKICBUUkFDRSgiKCVwLCVzKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBPTEVTVFIgKnBwc3pGaWxlTmFtZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBwc3pGaWxlTmFtZSk7CgogIGlmIChwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcHN6RmlsZU5hbWUgPSBOVUxMOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICBpZiAoVGhpcy0+cGFmLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgIGludCBsZW4gPSBsc3RybGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUpICsgMTsKCiAgICAqcHBzekZpbGVOYW1lID0gR2xvYmFsQWxsb2NQdHIoR0hORCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoKnBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBzdHJjcHlXKCpwcHN6RmlsZU5hbWUsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX0FkZFJlZigoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9SZWxlYXNlKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtICppZmFjZSwgTFBBUkFNIGxQYXJhbTEsCgkJCQkJICBMUEFSQU0gbFBhcmFtMikKewogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgaWZhY2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAvKiBUaGlzIElBVklTdHJlYW0gaW50ZXJmYWNlIG5lZWRzIGFuIFdBVkZpbGUgKi8KICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSAqaWZhY2UsTFBBVklTVFJFQU1JTkZPVyBwc2ksCgkJCQkJTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBpZmFjZSwgcHNpLCBzaXplKTsKCiAgaWYgKHBzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIG1lbWNweShwc2ksICZUaGlzLT5wYWYtPnNJbmZvLCBtaW4oKERXT1JEKXNpemUsIHNpemVvZihUaGlzLT5wYWYtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+cGFmLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwweCUwOGxYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICAvKiBEbyB3ZSBoYXZlIGRhdGE/ICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gLTE7CgogIC8qIFdlIGRvbid0IGhhdmUgYW4gaW5kZXggKi8KICBpZiAoZmxhZ3MgJiBGSU5EX0lOREVYKQogICAgcmV0dXJuIC0xOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpIHsKICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBmbGFncyAmPSB+KEZJTkRfRlJPTV9TVEFSVHxGSU5EX1BSRVYpOwogICAgZmxhZ3MgfD0gRklORF9ORVhUOwogIH0KCiAgaWYgKGZsYWdzICYgRklORF9GT1JNQVQpIHsKICAgIGlmICgoZmxhZ3MgJiBGSU5EX05FWFQpICYmIHBvcyA+IDApCiAgICAgIHBvcyA9IC0xOwogICAgZWxzZQogICAgICBwb3MgPSAwOwogIH0KCiAgaWYgKChmbGFncyAmIEZJTkRfUkVUKSA9PSBGSU5EX0xFTkdUSCB8fAogICAgICAoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gRklORF9TSVpFKQogICAgcmV0dXJuIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICBpZiAoKGZsYWdzICYgRklORF9SRVQpID09IEZJTkRfT0ZGU0VUKQogICAgcmV0dXJuIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKyBwb3MgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CgogIHJldHVybiBwb3M7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyAqZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKGZvcm1hdHNpemUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIG9ubHkgaW50ZXJlc3RlZCBpbiBuZWVkZWQgYnVmZmVyc2l6ZT8gKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgKmZvcm1hdHNpemUgPD0gMCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5wYWYtPmNiRm9ybWF0OwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IChvbmx5IGFzIG11Y2ggYXMgd2lsbCBmaXQpICovCiAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+cGFmLT5scEZvcm1hdCwgbWluKCpmb3JtYXRzaXplLCBUaGlzLT5wYWYtPmNiRm9ybWF0KSk7CiAgaWYgKCpmb3JtYXRzaXplIDwgVGhpcy0+cGFmLT5jYkZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5wYWYtPmNiRm9ybWF0OwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9CgogICpmb3JtYXRzaXplID0gVGhpcy0+cGFmLT5jYkZvcm1hdDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJWxkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IHNpemVvZihQQ01XQVZFRk9STUFUKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIFdlIGNhbiBvbmx5IGRvIHRoaXMgdG8gYW4gZW1wdHkgd2F2ZSBmaWxlLCBidXQgaWdub3JlIGNhbGwKICAgKiBpZiBzdGlsbCBzYW1lIGZvcm1hdCAqLwogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICBpZiAoZm9ybWF0c2l6ZSAhPSBUaGlzLT5jYkZvcm1hdCB8fAoJbWVtY21wKGZvcm1hdCwgVGhpcy0+bHBGb3JtYXQsIGZvcm1hdHNpemUpICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIG9ubHkgc3VwcG9ydCBzdGFydCBhdCBwb3NpdGlvbiAwICovCiAgaWYgKHBvcyAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGdldCBtZW1vcnkgZm9yIGZvcm1hdCBhbmQgY29weSBpdCAqLwogIFRoaXMtPmxwRm9ybWF0ID0gKExQV0FWRUZPUk1BVEVYKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIGZvcm1hdHNpemUpOwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIFRoaXMtPmNiRm9ybWF0ID0gZm9ybWF0c2l6ZTsKICBtZW1jcHkoVGhpcy0+bHBGb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIHVwZGF0ZSBpbmZvJ3MgYWJvdXQgJ2RhdGEnIGNodW5rICovCiAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IGZvcm1hdHNpemUgKyA3ICogc2l6ZW9mKERXT1JEKTsKICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gMDsKCiAgLyogZm9yIG5vbi1wY20gZm9ybWF0IHdlIG5lZWQgYWxzbyBhICdmYWN0JyBjaHVuayAqLwogIGlmIChUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pCiAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ICs9IDMgKiBzaXplb2YoRFdPUkQpOwoKICAvKiB1cGRhdGUgc3RyZWFtIGFuZCBmaWxlIGluZm8gKi8KICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTY2FsZSAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggICAgID0gMDsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCUxPTkcgYnVmZmVyc2l6ZSwgTFBMT05HIGJ5dGVzcmVhZCwKCQkJCQlMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBwb3NpdGlvbnMgd2l0aG91dCBkYXRhICovCiAgaWYgKHN0YXJ0IDwgMCB8fCAoRFdPUkQpc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIGNoZWNrIHNhbXBsZXMgKi8KICBpZiAoc2FtcGxlcyA8IDApCiAgICBzYW1wbGVzID0gMDsKICBpZiAoYnVmZmVyc2l6ZSA+IDApIHsKICAgIGlmIChzYW1wbGVzID4gMCkKICAgICAgc2FtcGxlcyA9IG1pbigoRFdPUkQpc2FtcGxlcywgYnVmZmVyc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSk7CiAgICBlbHNlCiAgICAgIHNhbXBsZXMgPSBidWZmZXJzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIH0KCiAgLyogbGltaXQgdG8gZW5kIG9mIHN0cmVhbSAqLwogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIHN0YXJ0OwoKICAvKiByZXF1ZXN0IG9ubHkgdGhlIHNpemVzPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCB8fCBidWZmZXJzaXplIDw9IDApIHsKICAgIC8qIHRoZW4gSSBuZWVkIGF0bGVhc3Qgb25lIHBhcmFtZXRlciBmb3IgaXQgKi8KICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogbm90aGluZyB0byByZWFkPyAqLwogIGlmIChzYW1wbGVzID09IDApCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBDYW4gSSBhdGxlYXN0IHJlYWQgb25lIHNhbXBsZT8gKi8KICBpZiAoKERXT1JEKWJ1ZmZlcnNpemUgPCBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwoKICBidWZmZXJzaXplID0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0CgkgICAgICAgKyBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSwgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilidWZmZXIsIGJ1ZmZlcnNpemUpICE9IGJ1ZmZlcnNpemUpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSBidWZmZXJzaXplOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsgIAoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgd2Ugd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiA8IDAgbWVhbnMgImFwcGVuZCIgKi8KICBpZiAoc3RhcnQgPCAwKQogICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGg7CgogIC8qIGNoZWNrIGJ1ZmZlcnNpemUgLS0gbXVzdCBtdWx0aXBsZSBvZiBzYW1wbGVzaXplICovCiAgaWYgKGJ1ZmZlcnNpemUgJiB+KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAtIDEpKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBoYXZlIHdlIGFueXRoaW5nIHRvIHdyaXRlPyAqLwogIGlmIChidWZmZXIgIT0gTlVMTCAmJiBidWZmZXJzaXplID4gMCkgewogICAgVGhpcy0+ZkRpcnR5ID0gMTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKwoJCSBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilidWZmZXIsIGJ1ZmZlcnNpemUpICE9IGJ1ZmZlcnNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gbWF4KFRoaXMtPnNJbmZvLmR3TGVuZ3RoLCAoRFdPUkQpc3RhcnQgKyBzYW1wbGVzKTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgID0gbWF4KFRoaXMtPmNrRGF0YS5ja3NpemUsCgkJCSAgICAgICBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSArIGJ1ZmZlcnNpemUpOwoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICAgKnNhbXB3cml0dGVuID0gc2FtcGxlczsKICAgIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICAgKmJ5dGVzd3JpdHRlbiA9IGJ1ZmZlcnNpemU7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgcGVybWlzc2lvbnMgKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpID49IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKSB7CiAgICAvKiBkZWxldGlvbiBhdCBlbmQgKi8KICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIHN0YXJ0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gc2FtcGxlczsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgIC09IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfSBlbHNlIGlmICgoRFdPUkQpc3RhcnQgPD0gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgLyogZGVsZXRpb24gYXQgc3RhcnQgKi8KICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd1N0YXJ0IC0gc3RhcnQ7CiAgICBzdGFydCAgID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKz0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgLT0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICB9IGVsc2UgewogICAgLyogZGVsZXRpb24gaW5zaWRlIHN0cmVhbSAtLSBuZWVkcyBwbGF5bGlzdCBhbmQgY3VlJ3MgKi8KICAgIEZJWE1FKCI6IGRlbGV0aW9uIGluc2lkZSBvZiBzdHJlYW0gbm90IHN1cHBvcnRlZCFcbiIpOwoKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICBUaGlzLT5mRGlydHkgPSAxOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9SZWFkRGF0YSgoUEFWSUZJTEUpVGhpcy0+cGFmLCBmY2MsIGxwLCBscHJlYWQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICByZXR1cm4gSUFWSUZpbGVfV3JpdGVEYXRhKChQQVZJRklMRSlUaGlzLT5wYWYsIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVsZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNTUNLSU5GTyBja1JJRkY7CiAgTU1DS0lORk8gY2s7CgogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gMDsgLyoganVzdCB0byBiZSBzdXJlICovCiAgVGhpcy0+ZkRpcnR5ID0gRkFMU0U7CgogIC8qIHNlYXJjaCBmb3IgUklGRiBjaHVuayAqLwogIGNrUklGRi5mY2NUeXBlID0gMDsgLyogZmluZCBhbnkgKi8KICBpZiAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIE5VTEwsIE1NSU9fRklORFJJRkYpICE9IFNfT0spIHsKICAgIHJldHVybiBBVklGSUxFX0xvYWRTdW5GaWxlKFRoaXMpOwogIH0KCiAgaWYgKGNrUklGRi5mY2NUeXBlICE9IGZvcm10eXBlV0FWRSkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBzZWFyY2ggV0FWRSBmb3JtYXQgY2h1bmsgKi8KICBjay5ja2lkID0gY2tpZFdBVkVGT1JNQVQ7CiAgaWYgKEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmV4dHJhLCBUaGlzLT5obW1pbywgJmNrLAoJCQkgICAgICZja1JJRkYsIE1NSU9fRklORENIVU5LKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgZm9ybWF0IGFuZCByZWFkIGl0ICovCiAgVGhpcy0+bHBGb3JtYXQgPSAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgY2suY2tzaXplKTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgVGhpcy0+Y2JGb3JtYXQgPSBjay5ja3NpemU7CgogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKVRoaXMtPmxwRm9ybWF0LCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIE5vbi1wY20gZm9ybWF0cyBoYXZlIGEgZmFjdCBjaHVuay4KICAgKiBXZSBkb24ndCBuZWVkIGl0LCBzbyBzaW1wbHkgYWRkIGl0IHRvIHRoZSBleHRyYSBjaHVua3MuCiAgICovCgogIC8qIGZpbmQgdGhlIGJpZyBkYXRhIGNodW5rICovCiAgVGhpcy0+Y2tEYXRhLmNraWQgPSBja2lkV0FWRURBVEE7CiAgaWYgKEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmV4dHJhLCBUaGlzLT5obW1pbywgJlRoaXMtPmNrRGF0YSwKCQkJICAgICAmY2tSSUZGLCBNTUlPX0ZJTkRDSFVOSykgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIG1lbXNldCgmVGhpcy0+c0luZm8sIDAsIHNpemVvZihUaGlzLT5zSW5mbykpOwogIFRoaXMtPnNJbmZvLmZjY1R5cGUgICAgICA9IHN0cmVhbXR5cGVBVURJTzsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjOwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9CiAgICBUaGlzLT5zSW5mby5kd1NjYWxlICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICAgICA9IFRoaXMtPmNrRGF0YS5ja3NpemUgLyBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID0gMTsKCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZUaGlzLT5ja0RhdGEsIDApICE9IFNfT0spIHsKICAgIC8qIHNlZW1zIHRvIGJlIHRydW5jYXRlZCAqLwogICAgV0FSTigiOiBmaWxlIHNlZW1zIHRvIGJlIHRydW5jYXRlZCFcbiIpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgPSBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19FTkQpIC0KICAgICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldDsKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZSAvIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICAgIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgfQoKICAvKiBpZ25vcmUgZXJyb3JzICovCiAgRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja1JJRkYsIDApOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRTdW5GaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIFNVTkFVRElPSEVBREVSIGF1aGRyOwoKICBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19TRVQpOwogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKSZhdWhkciwgc2l6ZW9mKGF1aGRyKSkgIT0gc2l6ZW9mKGF1aGRyKSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIGlmIChhdWhkci5mY2NUeXBlID09IDB4MDA2NDczMkUpIHsKICAgIC8qIGhlYWRlciBpbiBsaXR0bGUgZW5kaWFuICovCiAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gTEUySF9EV09SRChhdWhkci5vZmZzZXQpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IExFMkhfRFdPUkQoYXVoZHIuc2l6ZSk7CgogICAgYXVoZHIuZW5jb2RpbmcgICA9IExFMkhfRFdPUkQoYXVoZHIuZW5jb2RpbmcpOwogICAgYXVoZHIuc2FtcGxlUmF0ZSA9IExFMkhfRFdPUkQoYXVoZHIuc2FtcGxlUmF0ZSk7CiAgICBhdWhkci5jaGFubmVscyAgID0gTEUySF9EV09SRChhdWhkci5jaGFubmVscyk7CiAgfSBlbHNlIGlmIChhdWhkci5mY2NUeXBlID09IG1taW9GT1VSQ0MoJy4nLCdzJywnbicsJ2QnKSkgewogICAgLyogaGVhZGVyIGluIGJpZyBlbmRpYW4gKi8KICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSBCRTJIX0RXT1JEKGF1aGRyLm9mZnNldCk7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gQkUySF9EV09SRChhdWhkci5zaXplKTsKCiAgICBhdWhkci5lbmNvZGluZyAgID0gQkUySF9EV09SRChhdWhkci5lbmNvZGluZyk7CiAgICBhdWhkci5zYW1wbGVSYXRlID0gQkUySF9EV09SRChhdWhkci5zYW1wbGVSYXRlKTsKICAgIGF1aGRyLmNoYW5uZWxzICAgPSBCRTJIX0RXT1JEKGF1aGRyLmNoYW5uZWxzKTsKICB9IGVsc2UKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIGlmIChhdWhkci5jaGFubmVscyA8IDEpCiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgLyogZ2V0IHNpemUgb2YgaGVhZGVyICovCiAgc3dpdGNoKGF1aGRyLmVuY29kaW5nKSB7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIxXzMyOgogICAgVGhpcy0+Y2JGb3JtYXQgPSBzaXplb2YoRzcyMV9BRFBDTVdBVkVGT1JNQVQpOyBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQ6CiAgICBUaGlzLT5jYkZvcm1hdCA9IHNpemVvZihHNzIzX0FEUENNV0FWRUZPUk1BVCk7IGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyMjoKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfNToKICAgIFdBUk4oInVuc3VwcG9ydGVkIFN1biBhdWRpbyBmb3JtYXQgJWRcbiIsIGF1aGRyLmVuY29kaW5nKTsKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIEZJWE1FICovCiAgZGVmYXVsdDoKICAgIFRoaXMtPmNiRm9ybWF0ID0gc2l6ZW9mKFdBVkVGT1JNQVRFWCk7IGJyZWFrOwogIH07CgogIFRoaXMtPmxwRm9ybWF0ID0KICAgIChMUFdBVkVGT1JNQVRFWClHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBUaGlzLT5jYkZvcm1hdCk7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgVGhpcy0+bHBGb3JtYXQtPm5DaGFubmVscyAgICAgID0gYXVoZHIuY2hhbm5lbHM7CiAgVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjID0gYXVoZHIuc2FtcGxlUmF0ZTsKICBzd2l0Y2goYXVoZHIuZW5jb2RpbmcpIHsKICBjYXNlIEFVX0VOQ09ESU5HX1VMQVdfODoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX01VTEFXOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gODsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfUENNXzg6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSA4OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fMTY6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAxNjsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfUENNXzI0OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gMjQ7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV8zMjoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDMyOwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BTEFXXzg6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9BTEFXOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gODsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyMV8zMjoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX0c3MjFfQURQQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAoMyo1KjgpOwogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduICAgID0gMTUqMTUqODsKICAgIFRoaXMtPmxwRm9ybWF0LT5jYlNpemUgICAgICAgICA9IHNpemVvZihXT1JEKTsKICAgICgoTFBHNzIxX0FEUENNV0FWRUZPUk1BVClUaGlzLT5scEZvcm1hdCktPm5BdXhCbG9ja1NpemUgPSAwOwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIzXzI0OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfRzcyM19BRFBDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9ICgzKjUqOCk7CiAgICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gICAgPSAxNSoxNSo4OwogICAgVGhpcy0+bHBGb3JtYXQtPmNiU2l6ZSAgICAgICAgID0gMipzaXplb2YoV09SRCk7CiAgICAoKExQRzcyM19BRFBDTVdBVkVGT1JNQVQpVGhpcy0+bHBGb3JtYXQpLT5jYkV4dHJhU2l6ZSAgID0gMDsKICAgICgoTFBHNzIzX0FEUENNV0FWRUZPUk1BVClUaGlzLT5scEZvcm1hdCktPm5BdXhCbG9ja1NpemUgPSAwOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIFdBUk4oInVuc3VwcG9ydGVkIFN1biBhdWRpbyBmb3JtYXQgJWRcbiIsIGF1aGRyLmVuY29kaW5nKTsKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfTsKCiAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduID0KICAgIChUaGlzLT5scEZvcm1hdC0+bkNoYW5uZWxzICogVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlKSAvIDg7CiAgaWYgKFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiA9PSAwICYmIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA8IDgpCiAgICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24rKzsKICBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjID0KICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiAqIFRoaXMtPmxwRm9ybWF0LT5uU2FtcGxlc1BlclNlYzsKCiAgVGhpcy0+ZkRpcnR5ID0gMDsKCiAgVGhpcy0+c0luZm8uZmNjVHlwZSAgICAgICAgICAgICAgID0gc3RyZWFtdHlwZUFVRElPOwogIFRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdGbGFncyAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby53UHJpb3JpdHkgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLndMYW5ndWFnZSAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdJbml0aWFsRnJhbWVzICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYzsKICBUaGlzLT5zSW5mby5kd1N0YXJ0ICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplIC8gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAgICAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID0gMTsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgPSAxOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICA9IFRoaXMtPmxwRm9ybWF0LT5uU2FtcGxlc1BlclNlYzsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgPQogICAgTXVsRGl2KFRoaXMtPmNrRGF0YS5ja3NpemUsIFRoaXMtPmxwRm9ybWF0LT5uU2FtcGxlc1BlclNlYywKCSAgIFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWMpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1NQ0tJTkZPIGNrUklGRjsKICBNTUNLSU5GTyBjazsKCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfU0VUKTsKCiAgLyogY3JlYXRlIHRoZSBSSUZGIGNodW5rIHdpdGggZm9ybXR5cGUgV0FWRSAqLwogIGNrUklGRi5mY2NUeXBlID0gZm9ybXR5cGVXQVZFOwogIGNrUklGRi5ja3NpemUgID0gMDsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCBNTUlPX0NSRUFURVJJRkYpICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogdGhlIG5leHQgY2h1bmsgaXMgdGhlIGZvcm1hdCAqLwogIGNrLmNraWQgICA9IGNraWRXQVZFRk9STUFUOwogIGNrLmNrc2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMICYmIFRoaXMtPmNiRm9ybWF0ID4gMCkgewogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKVRoaXMtPmxwRm9ybWF0LCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogZmFjdCBjaHVuayBpcyBuZWVkZWQgZm9yIG5vbi1wY20gd2F2ZWZvcm1zICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwgJiYgVGhpcy0+Y2JGb3JtYXQgPiBzaXplb2YoUENNV0FWRUZPUk1BVCkgJiYKICAgICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgIT0gV0FWRV9GT1JNQVRfUENNKSB7CiAgICBXQVZFRk9STUFURVggd2Z4OwogICAgRFdPUkQgICAgICAgIGR3RmFjdExlbmd0aDsKICAgIEhBQ01TVFJFQU0gICBoYXM7CgogICAgLyogdHJ5IHRvIG9wZW4gYW4gYXBwcm9wcmlhdGUgYXVkaW8gY29kZWMgdG8gZmlndXJlIG91dAogICAgICogZGF0YSBmb3IgZmFjdC1jaHVuayAqLwogICAgd2Z4LndGb3JtYXRUYWcgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBpZiAoYWNtRm9ybWF0U3VnZ2VzdChOVUxMLCBUaGlzLT5scEZvcm1hdCwgJndmeCwKCQkJIHNpemVvZih3ZngpLCBBQ01fRk9STUFUU1VHR0VTVEZfV0ZPUk1BVFRBRykpIHsKICAgICAgYWNtU3RyZWFtT3BlbigmaGFzLCBOVUxMLCBUaGlzLT5scEZvcm1hdCwgJndmeCwgTlVMTCwKCQkgICAgMCwgMCwgQUNNX1NUUkVBTU9QRU5GX05PTlJFQUxUSU1FKTsKICAgICAgYWNtU3RyZWFtU2l6ZShoYXMsIFRoaXMtPmNrRGF0YS5ja3NpemUsICZkd0ZhY3RMZW5ndGgsCgkJICAgIEFDTV9TVFJFQU1TSVpFRl9TT1VSQ0UpOwogICAgICBkd0ZhY3RMZW5ndGggLz0gd2Z4Lm5CbG9ja0FsaWduOwogICAgICBhY21TdHJlYW1DbG9zZShoYXMsIDApOwoKICAgICAgLyogY3JldGUgdGhlIGZhY3QgY2h1bmsgKi8KICAgICAgY2suY2tpZCAgID0gY2tpZFdBVkVGQUNUOwogICAgICBjay5ja3NpemUgPSBzaXplb2YoZHdGYWN0TGVuZ3RoKTsKCiAgICAgIC8qIHRlc3QgZm9yIGVub3VnaCBzcGFjZSBiZWZvcmUgZGF0YSBjaHVuayAqLwogICAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfQ1VSKSA+IFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCSAgLSBjay5ja3NpemUgLSA0ICogc2l6ZW9mKERXT1JEKSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZkd0ZhY3RMZW5ndGgsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0gZWxzZQogICAgICBFUlIoIjogZmFjdCBjaHVuayBpcyBuZWVkZWQgZm9yIG5vbi1wY20gZmlsZXMgLS0gY3VycmVudGx5IG5vIGNvZGVjIGZvdW5kLCBzbyBza2lwcGVkIVxuIik7CiAgfQoKICAvKiBpZiBoZXJlIHdhcyBleHRyYSBzdHVmZiwgd2UgbmVlZCB0byBmaWxsIGl0IHdpdGggSlVOSyAqLwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19DVVIpICsgMiAqIHNpemVvZihEV09SRCkgPCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0KSB7CiAgICBjay5ja2lkICAgPSBja2lkQVZJUEFERElORzsKICAgIGNrLmNrc2l6ZSA9IDA7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJCSAtIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBjcmV0ZSB0aGUgZGF0YSBjaHVuayAqLwogIGNrLmNraWQgICA9IGNraWRXQVZFREFUQTsKICBjay5ja3NpemUgPSBUaGlzLT5ja0RhdGEuY2tzaXplOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgU0VFS19DVVIpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBzb21lIG9wdGlvbmFsIGV4dHJhIGNodW5rcz8gKi8KICBpZiAoVGhpcy0+ZXh0cmEubHAgIT0gTlVMTCAmJiBUaGlzLT5leHRyYS5jYiA+IDApIHsKICAgIC8qIGNodW5rIGhlYWRlcnMgYXJlIGFscmVhZHkgaW4gc3RydWN0dXJlICovCiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCBUaGlzLT5leHRyYS5scCwgVGhpcy0+ZXh0cmEuY2IpICE9IFRoaXMtPmV4dHJhLmNiKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CgogIC8qIGNsb3NlIFJJRkYgY2h1bmsgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvRmx1c2goVGhpcy0+aG1taW8sIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQo=