LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgojaW5jbHVkZSAiZXh0cmFjaHVuay5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIGZvcm10eXBlV0FWRSAgICBtbWlvRk9VUkNDKCdXJywnQScsJ1YnLCdFJykKI2RlZmluZSBja2lkV0FWRUZPUk1BVCAgbW1pb0ZPVVJDQygnZicsJ20nLCd0JywnICcpCiNkZWZpbmUgY2tpZFdBVkVGQUNUICAgIG1taW9GT1VSQ0MoJ2YnLCdhJywnYycsJ3QnKQojZGVmaW5lIGNraWRXQVZFREFUQSAgICBtbWlvRk9VUkNDKCdkJywnYScsJ3QnLCdhJykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgRU5ESUFOX1NXQVBXT1JEKHgpICAoKCgoeCkgPj4gOCkgJiAweEZGKSB8ICgoKHgpICYgMHhGRikgPDwgOCkpCiNkZWZpbmUgRU5ESUFOX1NXQVBEV09SRCh4KSAoRU5ESUFOX1NXQVBXT1JEKCh4ID4+IDE2KSAmIDB4RkZGRikgfCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRU5ESUFOX1NXQVBXT1JEKHggJiAweEZGRkYpIDw8IDE2KQoKI2lmZGVmIFdPUkRTX0JJR0VORElBTgojZGVmaW5lIEJFMkhfV09SRCh4KSAgKHgpCiNkZWZpbmUgQkUySF9EV09SRCh4KSAoeCkKI2RlZmluZSBMRTJIX1dPUkQoeCkgIEVORElBTl9TV0FQV09SRCh4KQojZGVmaW5lIExFMkhfRFdPUkQoeCkgRU5ESUFOX1NXQVBEV09SRCh4KQojZWxzZQojZGVmaW5lIEJFMkhfV09SRCh4KSAgRU5ESUFOX1NXQVBXT1JEKHgpCiNkZWZpbmUgQkUySF9EV09SRCh4KSBFTkRJQU5fU1dBUERXT1JEKHgpCiNkZWZpbmUgTEUySF9XT1JEKHgpICAoeCkKI2RlZmluZSBMRTJIX0RXT1JEKHgpICh4KQojZW5kaWYKCnR5cGVkZWYgc3RydWN0IHsKICBGT1VSQ0MgIGZjY1R5cGU7CiAgRFdPUkQgICBvZmZzZXQ7CiAgRFdPUkQgICBzaXplOwogIElOVCAgICAgZW5jb2Rpbmc7CiAgRFdPUkQgICBzYW1wbGVSYXRlOwogIERXT1JEICAgY2hhbm5lbHM7Cn0gU1VOQVVESU9IRUFERVI7CgojZGVmaW5lIEFVX0VOQ09ESU5HX1VMQVdfOCAgICAgICAgICAgICAgICAgMQojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV84ICAgICAgICAgICAgICAgICAgMgojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8xNiAgICAgICAgICAgICAgICAgMwojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8yNCAgICAgICAgICAgICAgICAgNAojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8zMiAgICAgICAgICAgICAgICAgNQojZGVmaW5lIEFVX0VOQ09ESU5HX0ZMT0FUICAgICAgICAgICAgICAgICAgNgojZGVmaW5lIEFVX0VOQ09ESU5HX0RPVUJMRSAgICAgICAgICAgICAgICAgNwojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzIgICAgICAgICAyMwojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjIgICAgICAgICAgICAyNAojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQgICAgICAgICAyNQojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfNSAgICAgICAgICAyNgojZGVmaW5lIEFVX0VOQ09ESU5HX0FMQVdfOCAgICAgICAgICAgICAgICAyNwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUqIGlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlKmlmYWNlLEFWSUZJTEVJTkZPVyphZmksTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuR2V0U3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxBVklTVFJFQU1JTkZPVyphc2kpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HICpzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRW5kUmVjb3JkKElBVklGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwoKc3RydWN0IElBVklGaWxlVnRibCBpd2F2ZnQgPSB7CiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdHJ1Y3QgSVBlcnNpc3RGaWxlVnRibCBpd2F2cGZ0ID0gewogIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElQZXJzaXN0RmlsZV9mbkFkZFJlZiwKICBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlLAogIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQsCiAgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eSwKICBJUGVyc2lzdEZpbGVfZm5Mb2FkLAogIElQZXJzaXN0RmlsZV9mblNhdmUsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZCwKICBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLExPTkcgKmJ5dGVzcmVhZCxMT05HICpzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0cnVjdCBJQVZJU3RyZWFtVnRibCBpd2F2c3QgPSB7CiAgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklTdHJlYW1fZm5BZGRSZWYsCiAgSUFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUFWSVN0cmVhbV9mbkNyZWF0ZSwKICBJQVZJU3RyZWFtX2ZuSW5mbywKICBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIElBVklTdHJlYW1fZm5SZWFkLAogIElBVklTdHJlYW1fZm5Xcml0ZSwKICBJQVZJU3RyZWFtX2ZuRGVsZXRlLAogIElBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhLAogIElBVklTdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSUZpbGVJbXBsIElBVklGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JUGVyc2lzdEZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElQZXJzaXN0RmlsZVZ0YmwgKmxwVnRibDsKCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElQZXJzaXN0RmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUFWSVN0cmVhbVZ0YmwgICAqbHBWdGJsOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElBVklTdHJlYW1JbXBsOwoKc3RydWN0IF9JQVZJRmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUFWSUZpbGVWdGJsICAgICAqbHBWdGJsOwogIERXT1JECQkgICAgcmVmOwoKICAvKiBJQVZJRmlsZSwgSUFWSVN0cmVhbSBzdHVmZi4uLiAqLwogIElQZXJzaXN0RmlsZUltcGwgIGlQZXJzaXN0RmlsZTsKICBJQVZJU3RyZWFtSW1wbCAgICBpQVZJU3RyZWFtOwoKICBBVklGSUxFSU5GT1cgICAgICBmSW5mbzsKICBBVklTVFJFQU1JTkZPVyAgICBzSW5mbzsKCiAgTFBXQVZFRk9STUFURVggICAgbHBGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgICAgY2JGb3JtYXQ7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrRGF0YTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZXh0cmE7CgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAuLi4gKi8KICBITU1JTyAgICAgICAgICAgICBobW1pbzsKICBMUFdTVFIgICAgICAgICAgICBzekZpbGVOYW1lOwogIFVJTlQgICAgICAgICAgICAgIHVNb2RlOwogIEJPT0wgICAgICAgICAgICAgIGZEaXJ0eTsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkU3VuRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlV0FWRmlsZShSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICBJQVZJRmlsZUltcGwgKnBmaWxlOwogIEhSRVNVTFQgICAgICAgaHI7CgogIGFzc2VydChyaWlkICE9IE5VTEwgJiYgcHB2ICE9IE5VTEwpOwoKICAqcHB2ID0gTlVMTDsKCiAgcGZpbGUgPSAoSUFWSUZpbGVJbXBsKilMb2NhbEFsbG9jKExQVFIsIHNpemVvZihJQVZJRmlsZUltcGwpKTsKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwZmlsZS0+bHBWdGJsICAgICAgICAgICAgICAgID0gJml3YXZmdDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLmxwVnRibCAgID0gJml3YXZwZnQ7CiAgcGZpbGUtPmlBVklTdHJlYW0ubHBWdGJsICAgICA9ICZpd2F2c3Q7CiAgcGZpbGUtPnJlZiA9IDA7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5wYWYgPSBwZmlsZTsKICBwZmlsZS0+aUFWSVN0cmVhbS5wYWYgICA9IHBmaWxlOwoKICBociA9IElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChJQVZJRmlsZSopcGZpbGUsIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBMb2NhbEZyZWUoKEhMT0NBTClwZmlsZSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUgKmlmYWNlLCBSRUZJSUQgcmVmaWlkLAoJCQkJCQlMUFZPSUQgKm9iaikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgPT0gMSAmJgoJICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUFWSVN0cmVhbTsKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUGVyc2lzdEZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aVBlcnNpc3RGaWxlOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICghcmVmKSB7CiAgICBpZiAoVGhpcy0+ZkRpcnR5KSB7CiAgICAgIC8qIG5lZWQgdG8gd3JpdGUgaGVhZGVycyB0byBmaWxlICovCiAgICAgIEFWSUZJTEVfU2F2ZUZpbGUoVGhpcyk7CiAgICB9CgogICAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scEZvcm1hdCk7CiAgICAgIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JGb3JtYXQgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPmV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5leHRyYS5scCk7CiAgICAgIFRoaXMtPmV4dHJhLmxwID0gTlVMTDsKICAgICAgVGhpcy0+ZXh0cmEuY2IgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzLT5zekZpbGVOYW1lKTsKICAgICAgVGhpcy0+c3pGaWxlTmFtZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkgewogICAgICBtbWlvQ2xvc2UoVGhpcy0+aG1taW8sIDApOwogICAgICBUaGlzLT5obW1pbyA9IE5VTEw7CiAgICB9CgogICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcyk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSAqaWZhY2UsIExQQVZJRklMRUlORk9XIGFmaSwKCQkJCSAgICAgIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLGlmYWNlLGFmaSxzaXplKTsKCiAgaWYgKGFmaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIHVwZGF0ZSBmaWxlIGluZm8gKi8KICBUaGlzLT5mSW5mby5kd0ZsYWdzID0gMDsKICBUaGlzLT5mSW5mby5kd0NhcHMgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U2NhbGUgIT0gMCk7CgogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICAgICAgICAgICAgID0gMTsKICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3U2NhbGU7CiAgICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBUaGlzLT5zSW5mby5kd1JhdGU7CiAgICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICAgIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjID0KICAgICAgTXVsRGl2KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSxUaGlzLT5zSW5mby5kd1JhdGUsVGhpcy0+c0luZm8uZHdTY2FsZSk7CiAgfQoKICBtZW1jcHkoYWZpLCAmVGhpcy0+ZkluZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+ZkluZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4bFgsJWxkKVxuIiwgaWZhY2UsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChhdmlzID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqYXZpcyA9IE5VTEw7CgogIC8qIERvZXMgb3VyIHN0cmVhbSBleGlzdHM/ICovCiAgaWYgKGxQYXJhbSAhPSAwIHx8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CiAgaWYgKGZjY1R5cGUgIT0gMCAmJiBmY2NUeXBlICE9IHN0cmVhbXR5cGVBVURJTykKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwoKICAqYXZpcyA9IChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtOwogIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsUEFWSVNUUkVBTSAqYXZpcywKCQkJCQkgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCBhdmlzLCBhc2kpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBhc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogV2Ugb25seSBzdXBwb3J0IG9uZSBhdWRpbyBzdHJlYW0gKi8KICBpZiAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zICE9IDAgfHwgVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgaWYgKGFzaS0+ZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5jYkZvcm1hdCA9IDA7CiAgVGhpcy0+bHBGb3JtYXQgPSBOVUxMOwoKICBtZW1jcHkoJlRoaXMtPnNJbmZvLCBhc2ksIHNpemVvZihUaGlzLT5zSW5mbykpOwoKICAvKiBtYWtlIHN1cmUgc3RyZWFtaW5mbyBpZiBva2F5IGZvciB1cyAqLwogIFRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3RmxhZ3MgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3Q2FwcyAgICAgICAgICAgICAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIFRoaXMtPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgPSAwOwogIG1lbXNldCgmVGhpcy0+c0luZm8ucmNGcmFtZSwgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvLnJjRnJhbWUpKTsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID0gMTsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgPSBUaGlzLT5zSW5mby5kd1NjYWxlOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICA9IFRoaXMtPnNJbmZvLmR3UmF0ZTsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKCiAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IDA7CiAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IDA7CgogICphdmlzID0gKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW07CiAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgICBMUFZPSUQgbHBEYXRhLCBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlbGQpXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscERhdGEgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgcmV0dXJuIFdyaXRlRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgIExQVk9JRCBscERhdGEsIExPTkcgKnNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUgKmlmYWNlKQp7CiAgVFJBQ0UoIiglcClcbiIsaWZhY2UpOwoKICAvKiBUaGlzIGlzIG9ubHkgbmVlZGVkIGZvciBpbnRlcmxlYXZlZCBmaWxlcy4KICAgKiBXZSBoYXZlIG9ubHkgb25lIHN0cmVhbSwgd2hpY2ggY2FuJ3QgYmUgaW50ZXJsZWF2ZWQuCiAgICovCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlICppZmFjZSwgRFdPUkQgZmNjVHlwZSwKCQkJCQkgICAgICBMT05HIGxQYXJhbSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVsZClcbiIsIGlmYWNlLCBmY2NUeXBlLCBsUGFyYW0pOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgKi8KICBpZiAobFBhcmFtIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERvIHdlIGhhdmUgb3VyIGF1ZGlvIHN0cmVhbT8gKi8KICBpZiAobFBhcmFtICE9IDAgfHwgVGhpcy0+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+c0luZm8uZHdTYW1wbGVTaXplOwogIH0KCiAgLyogbGltaXQgdG8gZW5kIG9mIHN0cmVhbSAqLwogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIHN0YXJ0OwoKICAvKiByZXF1ZXN0IG9ubHkgdGhlIHNpemVzPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCB8fCBidWZmZXJzaXplIDw9IDApIHsKICAgIC8qIHRoZW4gSSBuZWVkIGF0IGxlYXN0IG9uZSBwYXJhbWV0ZXIgZm9yIGl0ICovCiAgICBpZiAoYnl0ZXNyZWFkID09IE5VTEwgJiYgc2FtcGxlc3JlYWQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIG5vdGhpbmcgdG8gcmVhZD8gKi8KICBpZiAoc2FtcGxlcyA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogQ2FuIEkgcmVhZCBhdCBsZWFzdCBvbmUgc2FtcGxlPyAqLwogIGlmICgoRFdPUkQpYnVmZmVyc2l6ZSA8IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogIGJ1ZmZlcnNpemUgPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCSAgICAgICArIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgYnVmZmVyc2l6ZSkgIT0gYnVmZmVyc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IGJ1ZmZlcnNpemU7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOyAgCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywKCWJ1ZmZlciwgYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCAmJiAoYnVmZmVyc2l6ZSA+IDAgfHwgc2FtcGxlcyA+IDApKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIDwgMCBtZWFucyAiYXBwZW5kIiAqLwogIGlmIChzdGFydCA8IDApCiAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aDsKCiAgLyogY2hlY2sgYnVmZmVyc2l6ZSAtLSBtdXN0IG11bHRpcGxlIG9mIHNhbXBsZXNpemUgKi8KICBpZiAoYnVmZmVyc2l6ZSAmIH4oVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplIC0gMSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIGRvIHdlIGhhdmUgYW55dGhpbmcgdG8gd3JpdGU/ICovCiAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICBUaGlzLT5mRGlydHkgPSAxOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArCgkJIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgYnVmZmVyc2l6ZSkgIT0gYnVmZmVyc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBtYXgoVGhpcy0+c0luZm8uZHdMZW5ndGgsIChEV09SRClzdGFydCArIHNhbXBsZXMpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgPSBtYXgoVGhpcy0+Y2tEYXRhLmNrc2l6ZSwKCQkJICAgICAgIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICsgYnVmZmVyc2l6ZSk7CgogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgICAqc2FtcHdyaXR0ZW4gPSBzYW1wbGVzOwogICAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgICAqYnl0ZXN3cml0dGVuID0gYnVmZmVyc2l6ZTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLCVsZClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3RhcnQgPCAwIHx8IHNhbXBsZXMgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRGVsZXRlIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBEZWxldGUgYWZ0ZXIgZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoKERXT1JEKXN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBGb3IgdGhlIHJlc3Qgd2UgbmVlZCB3cml0ZSBwZXJtaXNzaW9ucyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPj0gVGhpcy0+c0luZm8uZHdMZW5ndGgpIHsKICAgIC8qIGRlbGV0aW9uIGF0IGVuZCAqLwogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc3RhcnQ7CiAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBzYW1wbGVzOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgLT0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICB9IGVsc2UgaWYgKChEV09SRClzdGFydCA8PSBUaGlzLT5zSW5mby5kd1N0YXJ0KSB7CiAgICAvKiBkZWxldGlvbiBhdCBzdGFydCAqLwogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgLSBzdGFydDsKICAgIHN0YXJ0ICAgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICAtPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIH0gZWxzZSB7CiAgICAvKiBkZWxldGlvbiBpbnNpZGUgc3RyZWFtIC0tIG5lZWRzIHBsYXlsaXN0IGFuZCBjdWUncyAqLwogICAgRklYTUUoIjogZGVsZXRpb24gaW5zaWRlIG9mIHN0cmVhbSBub3Qgc3VwcG9ydGVkIVxuIik7CgogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIFRoaXMtPmZEaXJ0eSA9IDE7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgTFBWT0lEIGxwLCBMUExPTkcgbHByZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlYWREYXRhKChQQVZJRklMRSlUaGlzLT5wYWYsIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgICBMUFZPSUQgbHAsIExPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIHJldHVybiBJQVZJRmlsZV9Xcml0ZURhdGEoKFBBVklGSUxFKVRoaXMtPnBhZiwgZmNjLCBscCwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkgICBMUEFWSVNUUkVBTUlORk9XIGluZm8sIExPTkcgaW5mb2xlbikKewogIEZJWE1FKCIoJXAsJXAsJWxkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1NQ0tJTkZPIGNrUklGRjsKICBNTUNLSU5GTyBjazsKCiAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSAwOyAvKiBqdXN0IHRvIGJlIHN1cmUgKi8KICBUaGlzLT5mRGlydHkgPSBGQUxTRTsKCiAgLyogc2VhcmNoIGZvciBSSUZGIGNodW5rICovCiAgY2tSSUZGLmZjY1R5cGUgPSAwOyAvKiBmaW5kIGFueSAqLwogIGlmIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgTlVMTCwgTU1JT19GSU5EUklGRikgIT0gU19PSykgewogICAgcmV0dXJuIEFWSUZJTEVfTG9hZFN1bkZpbGUoVGhpcyk7CiAgfQoKICBpZiAoY2tSSUZGLmZjY1R5cGUgIT0gZm9ybXR5cGVXQVZFKQogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogIC8qIHNlYXJjaCBXQVZFIGZvcm1hdCBjaHVuayAqLwogIGNrLmNraWQgPSBja2lkV0FWRUZPUk1BVDsKICBpZiAoRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssCgkJCSAgICAgJmNrUklGRiwgTU1JT19GSU5EQ0hVTkspICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIHJlYWQgaXQgKi8KICBUaGlzLT5scEZvcm1hdCA9IChMUFdBVkVGT1JNQVRFWClHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBjay5ja3NpemUpOwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBUaGlzLT5jYkZvcm1hdCA9IGNrLmNrc2l6ZTsKCiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogTm9uLXBjbSBmb3JtYXRzIGhhdmUgYSBmYWN0IGNodW5rLgogICAqIFdlIGRvbid0IG5lZWQgaXQsIHNvIHNpbXBseSBhZGQgaXQgdG8gdGhlIGV4dHJhIGNodW5rcy4KICAgKi8KCiAgLyogZmluZCB0aGUgYmlnIGRhdGEgY2h1bmsgKi8KICBUaGlzLT5ja0RhdGEuY2tpZCA9IGNraWRXQVZFREFUQTsKICBpZiAoRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tEYXRhLAoJCQkgICAgICZja1JJRkYsIE1NSU9fRklORENIVU5LKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgbWVtc2V0KCZUaGlzLT5zSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgVGhpcy0+c0luZm8uZmNjVHlwZSAgICAgID0gc3RyZWFtdHlwZUFVRElPOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0KICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggICAgID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZSAvIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0RhdGEuY2tzaXplOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwoKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJlRoaXMtPmNrRGF0YSwgMCkgIT0gU19PSykgewogICAgLyogc2VlbXMgdG8gYmUgdHJ1bmNhdGVkICovCiAgICBXQVJOKCI6IGZpbGUgc2VlbXMgdG8gYmUgdHJ1bmNhdGVkIVxuIik7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICA9IG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX0VORCkgLQogICAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBUaGlzLT5ja0RhdGEuY2tzaXplIC8gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogICAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICB9CgogIC8qIGlnbm9yZSBlcnJvcnMgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5leHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrUklGRiwgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZFN1bkZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgU1VOQVVESU9IRUFERVIgYXVoZHI7CgogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX1NFVCk7CiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmF1aGRyLCBzaXplb2YoYXVoZHIpKSAhPSBzaXplb2YoYXVoZHIpKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgaWYgKGF1aGRyLmZjY1R5cGUgPT0gMHgwMDY0NzMyRSkgewogICAgLyogaGVhZGVyIGluIGxpdHRsZSBlbmRpYW4gKi8KICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSBMRTJIX0RXT1JEKGF1aGRyLm9mZnNldCk7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gTEUySF9EV09SRChhdWhkci5zaXplKTsKCiAgICBhdWhkci5lbmNvZGluZyAgID0gTEUySF9EV09SRChhdWhkci5lbmNvZGluZyk7CiAgICBhdWhkci5zYW1wbGVSYXRlID0gTEUySF9EV09SRChhdWhkci5zYW1wbGVSYXRlKTsKICAgIGF1aGRyLmNoYW5uZWxzICAgPSBMRTJIX0RXT1JEKGF1aGRyLmNoYW5uZWxzKTsKICB9IGVsc2UgaWYgKGF1aGRyLmZjY1R5cGUgPT0gbW1pb0ZPVVJDQygnLicsJ3MnLCduJywnZCcpKSB7CiAgICAvKiBoZWFkZXIgaW4gYmlnIGVuZGlhbiAqLwogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IEJFMkhfRFdPUkQoYXVoZHIub2Zmc2V0KTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSBCRTJIX0RXT1JEKGF1aGRyLnNpemUpOwoKICAgIGF1aGRyLmVuY29kaW5nICAgPSBCRTJIX0RXT1JEKGF1aGRyLmVuY29kaW5nKTsKICAgIGF1aGRyLnNhbXBsZVJhdGUgPSBCRTJIX0RXT1JEKGF1aGRyLnNhbXBsZVJhdGUpOwogICAgYXVoZHIuY2hhbm5lbHMgICA9IEJFMkhfRFdPUkQoYXVoZHIuY2hhbm5lbHMpOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgaWYgKGF1aGRyLmNoYW5uZWxzIDwgMSkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBnZXQgc2l6ZSBvZiBoZWFkZXIgKi8KICBzd2l0Y2goYXVoZHIuZW5jb2RpbmcpIHsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzI6CiAgICBUaGlzLT5jYkZvcm1hdCA9IHNpemVvZihHNzIxX0FEUENNV0FWRUZPUk1BVCk7IGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM18yNDoKICAgIFRoaXMtPmNiRm9ybWF0ID0gc2l6ZW9mKEc3MjNfQURQQ01XQVZFRk9STUFUKTsgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIyOgogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM181OgogICAgV0FSTigidW5zdXBwb3J0ZWQgU3VuIGF1ZGlvIGZvcm1hdCAlZFxuIiwgYXVoZHIuZW5jb2RpbmcpOwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogRklYTUUgKi8KICBkZWZhdWx0OgogICAgVGhpcy0+Y2JGb3JtYXQgPSBzaXplb2YoV0FWRUZPUk1BVEVYKTsgYnJlYWs7CiAgfTsKCiAgVGhpcy0+bHBGb3JtYXQgPQogICAgKExQV0FWRUZPUk1BVEVYKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIFRoaXMtPmNiRm9ybWF0KTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBUaGlzLT5scEZvcm1hdC0+bkNoYW5uZWxzICAgICAgPSBhdWhkci5jaGFubmVsczsKICBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWMgPSBhdWhkci5zYW1wbGVSYXRlOwogIHN3aXRjaChhdWhkci5lbmNvZGluZykgewogIGNhc2UgQVVfRU5DT0RJTkdfVUxBV184OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfTVVMQVc7CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSA4OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fODoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDg7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV8xNjoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDE2OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fMjQ6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAyNDsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfUENNXzMyOgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gMzI7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FMQVdfODoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX0FMQVc7CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSA4OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIxXzMyOgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfRzcyMV9BRFBDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9ICgzKjUqOCk7CiAgICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gICAgPSAxNSoxNSo4OwogICAgVGhpcy0+bHBGb3JtYXQtPmNiU2l6ZSAgICAgICAgID0gc2l6ZW9mKFdPUkQpOwogICAgKChMUEc3MjFfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+bkF1eEJsb2NrU2l6ZSA9IDA7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQ6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9HNzIzX0FEUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gKDMqNSo4KTsKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiAgICA9IDE1KjE1Kjg7CiAgICBUaGlzLT5scEZvcm1hdC0+Y2JTaXplICAgICAgICAgPSAyKnNpemVvZihXT1JEKTsKICAgICgoTFBHNzIzX0FEUENNV0FWRUZPUk1BVClUaGlzLT5scEZvcm1hdCktPmNiRXh0cmFTaXplICAgPSAwOwogICAgKChMUEc3MjNfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+bkF1eEJsb2NrU2l6ZSA9IDA7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgV0FSTigidW5zdXBwb3J0ZWQgU3VuIGF1ZGlvIGZvcm1hdCAlZFxuIiwgYXVoZHIuZW5jb2RpbmcpOwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9OwoKICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gPQogICAgKFRoaXMtPmxwRm9ybWF0LT5uQ2hhbm5lbHMgKiBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUpIC8gODsKICBpZiAoVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduID09IDAgJiYgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlIDwgOCkKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbisrOwogIFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWMgPQogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduICogVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjOwoKICBUaGlzLT5mRGlydHkgPSAwOwoKICBUaGlzLT5zSW5mby5mY2NUeXBlICAgICAgICAgICAgICAgPSBzdHJlYW10eXBlQVVESU87CiAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLndQcmlvcml0eSAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8ud0xhbmd1YWdlICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjOwogIFRoaXMtPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggICAgICAgICAgICAgID0KICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgLyBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICAgICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICA9IDE7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgID0gVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICA9CiAgICBNdWxEaXYoVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjLAoJICAgVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTU1DS0lORk8gY2tSSUZGOwogIE1NQ0tJTkZPIGNrOwoKICBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19TRVQpOwoKICAvKiBjcmVhdGUgdGhlIFJJRkYgY2h1bmsgd2l0aCBmb3JtdHlwZSBXQVZFICovCiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZVdBVkU7CiAgY2tSSUZGLmNrc2l6ZSAgPSAwOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiB0aGUgbmV4dCBjaHVuayBpcyB0aGUgZm9ybWF0ICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVGT1JNQVQ7CiAgY2suY2tzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwgJiYgVGhpcy0+Y2JGb3JtYXQgPiAwKSB7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBmYWN0IGNodW5rIGlzIG5lZWRlZCBmb3Igbm9uLXBjbSB3YXZlZm9ybXMgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCAmJiBUaGlzLT5jYkZvcm1hdCA+IHNpemVvZihQQ01XQVZFRk9STUFUKSAmJgogICAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pIHsKICAgIFdBVkVGT1JNQVRFWCB3Zng7CiAgICBEV09SRCAgICAgICAgZHdGYWN0TGVuZ3RoOwogICAgSEFDTVNUUkVBTSAgIGhhczsKCiAgICAvKiB0cnkgdG8gb3BlbiBhbiBhcHByb3ByaWF0ZSBhdWRpbyBjb2RlYyB0byBmaWd1cmUgb3V0CiAgICAgKiBkYXRhIGZvciBmYWN0LWNodW5rICovCiAgICB3Zngud0Zvcm1hdFRhZyA9IFdBVkVfRk9STUFUX1BDTTsKICAgIGlmIChhY21Gb3JtYXRTdWdnZXN0KE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LAoJCQkgc2l6ZW9mKHdmeCksIEFDTV9GT1JNQVRTVUdHRVNURl9XRk9STUFUVEFHKSkgewogICAgICBhY21TdHJlYW1PcGVuKCZoYXMsIE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LCBOVUxMLAoJCSAgICAwLCAwLCBBQ01fU1RSRUFNT1BFTkZfTk9OUkVBTFRJTUUpOwogICAgICBhY21TdHJlYW1TaXplKGhhcywgVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgJmR3RmFjdExlbmd0aCwKCQkgICAgQUNNX1NUUkVBTVNJWkVGX1NPVVJDRSk7CiAgICAgIGR3RmFjdExlbmd0aCAvPSB3ZngubkJsb2NrQWxpZ247CiAgICAgIGFjbVN0cmVhbUNsb3NlKGhhcywgMCk7CgogICAgICAvKiBjcmVhdGUgdGhlIGZhY3QgY2h1bmsgKi8KICAgICAgY2suY2tpZCAgID0gY2tpZFdBVkVGQUNUOwogICAgICBjay5ja3NpemUgPSBzaXplb2YoZHdGYWN0TGVuZ3RoKTsKCiAgICAgIC8qIHRlc3QgZm9yIGVub3VnaCBzcGFjZSBiZWZvcmUgZGF0YSBjaHVuayAqLwogICAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfQ1VSKSA+IFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCSAgLSBjay5ja3NpemUgLSA0ICogc2l6ZW9mKERXT1JEKSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZkd0ZhY3RMZW5ndGgsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0gZWxzZQogICAgICBFUlIoIjogZmFjdCBjaHVuayBpcyBuZWVkZWQgZm9yIG5vbi1wY20gZmlsZXMgLS0gY3VycmVudGx5IG5vIGNvZGVjIGZvdW5kLCBzbyBza2lwcGVkIVxuIik7CiAgfQoKICAvKiBpZiB0aGVyZSB3YXMgZXh0cmEgc3R1ZmYsIHdlIG5lZWQgdG8gZmlsbCBpdCB3aXRoIEpVTksgKi8KICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfQ1VSKSArIDIgKiBzaXplb2YoRFdPUkQpIDwgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCkgewogICAgY2suY2tpZCAgID0gY2tpZEFWSVBBRERJTkc7CiAgICBjay5ja3NpemUgPSAwOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCQkgLSAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY3JlYXRlIHRoZSBkYXRhIGNodW5rICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVEQVRBOwogIGNrLmNrc2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuY2tzaXplLCBTRUVLX0NVUikgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHNvbWUgb3B0aW9uYWwgZXh0cmEgY2h1bmtzPyAqLwogIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMICYmIFRoaXMtPmV4dHJhLmNiID4gMCkgewogICAgLyogY2h1bmsgaGVhZGVycyBhcmUgYWxyZWFkeSBpbiBzdHJ1Y3R1cmUgKi8KICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIFRoaXMtPmV4dHJhLmxwLCBUaGlzLT5leHRyYS5jYikgIT0gVGhpcy0+ZXh0cmEuY2IpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY2xvc2UgUklGRiBjaHVuayAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9GbHVzaChUaGlzLT5obW1pbywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==