LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZG93c3guaCIKI2luY2x1ZGUgInZmdy5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKI2lmbmRlZiBESUJQVFIKI2RlZmluZSBESUJQVFIobHApICAgICAgKChMUEJZVEUpKGxwKSArIChscCktPmJpU2l6ZSArIFwKICAgICAgICAgICAgICAgICAgICAgICAgIChscCktPmJpQ2xyVXNlZCAqIHNpemVvZihSR0JRVUFEKSkKI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUdldEZyYW1lX2ZuUXVlcnlJbnRlcmZhY2UoSUdldEZyYW1lICppZmFjZSwKCQkJCQkJIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElHZXRGcmFtZV9mbkFkZFJlZihJR2V0RnJhbWUgKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElHZXRGcmFtZV9mblJlbGVhc2UoSUdldEZyYW1lICppZmFjZSk7CnN0YXRpYyBMUFZPSUQgIFdJTkFQSSBJR2V0RnJhbWVfZm5HZXRGcmFtZShJR2V0RnJhbWUgKmlmYWNlLCBMT05HIGxQb3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUdldEZyYW1lX2ZuQmVnaW4oSUdldEZyYW1lICppZmFjZSwgTE9ORyBsU3RhcnQsCgkJCQkJTE9ORyBsRW5kLCBMT05HIGxSYXRlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElHZXRGcmFtZV9mbkVuZChJR2V0RnJhbWUgKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElHZXRGcmFtZV9mblNldEZvcm1hdChJR2V0RnJhbWUgKmlmYWNlLAoJCQkJCSAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaSwKCQkJCQkgICAgTFBWT0lEIGxwQml0cywgSU5UIHgsIElOVCB5LAoJCQkJCSAgICBJTlQgZHgsIElOVCBkeSk7CgpzdHJ1Y3QgSUNPTV9WVEFCTEUoSUdldEZyYW1lKSBpZ2V0ZnJhbWVWdGJsID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSUdldEZyYW1lX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUdldEZyYW1lX2ZuQWRkUmVmLAogIElHZXRGcmFtZV9mblJlbGVhc2UsCiAgSUdldEZyYW1lX2ZuR2V0RnJhbWUsCiAgSUdldEZyYW1lX2ZuQmVnaW4sCiAgSUdldEZyYW1lX2ZuRW5kLAogIElHZXRGcmFtZV9mblNldEZvcm1hdAp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lHZXRGcmFtZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUNPTV9WRklFTEQoSUdldEZyYW1lKTsKICBEV09SRCAgICAgICAgICAgICAgcmVmOwoKICAvKiBJR2V0RnJhbWUgc3R1ZmYgKi8KICBCT09MICAgICAgICAgICAgICAgYkZpeGVkU3RyZWFtOwogIFBBVklTVFJFQU0gICAgICAgICBwU3RyZWFtOwoKICBMUFZPSUQgICAgICAgICAgICAgbHBJbkJ1ZmZlcjsKICBMT05HICAgICAgICAgICAgICAgY2JJbkJ1ZmZlcjsKICBMUEJJVE1BUElORk9IRUFERVIgbHBJbkZvcm1hdDsKICBMT05HICAgICAgICAgICAgICAgY2JJbkZvcm1hdDsKCiAgTE9ORyAgICAgICAgICAgICAgIGxDdXJyZW50RnJhbWU7CiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwT3V0Rm9ybWF0OwogIExQVk9JRCAgICAgICAgICAgICBscE91dEJ1ZmZlcjsKCiAgSElDICAgICAgICAgICAgICAgIGhpYzsKICBCT09MICAgICAgICAgICAgICAgYlJlc2l6ZTsKICBEV09SRCAgICAgICAgICAgICAgeDsKICBEV09SRCAgICAgICAgICAgICAgeTsKICBEV09SRCAgICAgICAgICAgICAgZHg7CiAgRFdPUkQgICAgICAgICAgICAgIGR5OwoKICBCT09MICAgICAgICAgICAgICAgYkZvcm1hdENoYW5nZXM7CiAgRFdPUkQgICAgICAgICAgICAgIGR3Rm9ybWF0Q2hhbmdlQ291bnQ7CiAgRFdPUkQgICAgICAgICAgICAgIGR3RWRpdENvdW50Owp9IElHZXRGcmFtZUltcGw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihJR2V0RnJhbWVJbXBsICpUaGlzKQp7CiAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ICE9IE5VTEwgJiYgVGhpcy0+bHBJbkZvcm1hdCAhPSBUaGlzLT5scE91dEZvcm1hdCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scE91dEZvcm1hdCk7CiAgICBUaGlzLT5scE91dEZvcm1hdCA9IE5VTEw7CiAgfQogIGlmIChUaGlzLT5scEluRm9ybWF0ICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBJbkZvcm1hdCk7CiAgICBUaGlzLT5scEluRm9ybWF0ID0gTlVMTDsKICB9CiAgaWYgKFRoaXMtPmhpYyAhPSBOVUxMKSB7CiAgICBpZiAoVGhpcy0+YlJlc2l6ZSkKICAgICAgSUNEZWNvbXByZXNzRXhFbmQoVGhpcy0+aGljKTsKICAgIGVsc2UKICAgICAgSUNEZWNvbXByZXNzRW5kKFRoaXMtPmhpYyk7CiAgICBJQ0Nsb3NlKFRoaXMtPmhpYyk7CiAgICBUaGlzLT5oaWMgPSBOVUxMOwogIH0KfQoKUEdFVEZSQU1FIEFWSUZJTEVfQ3JlYXRlR2V0RnJhbWUoUEFWSVNUUkVBTSBwU3RyZWFtKQp7CiAgSUdldEZyYW1lSW1wbCAqcGc7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gTlVMTDsKCiAgcGcgPSAoSUdldEZyYW1lSW1wbCopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSUdldEZyYW1lSW1wbCkpOwogIGlmIChwZyAhPSBOVUxMKSB7CiAgICBwZy0+bHBWdGJsICAgICAgICA9ICZpZ2V0ZnJhbWVWdGJsOwogICAgcGctPnJlZiAgICAgICAgICAgPSAxOwogICAgcGctPmxDdXJyZW50RnJhbWUgPSAtMTsKICAgIHBnLT5wU3RyZWFtICAgICAgID0gcFN0cmVhbTsKICAgIElBVklTdHJlYW1fQWRkUmVmKHBTdHJlYW0pOwogIH0KCiAgcmV0dXJuIChQR0VURlJBTUUpcGc7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJR2V0RnJhbWVfZm5RdWVyeUludGVyZmFjZShJR2V0RnJhbWUgKmlmYWNlLAoJCQkJCQkgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQ09NX1RISVMoSUdldEZyYW1lSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUdldEZyYW1lLCByZWZpaWQpKSB7CiAgICAqb2JqID0gaWZhY2U7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElHZXRGcmFtZV9mbkFkZFJlZihJR2V0RnJhbWUgKmlmYWNlKQp7CiAgSUNPTV9USElTKElHZXRGcmFtZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElHZXRGcmFtZV9mblJlbGVhc2UoSUdldEZyYW1lICppZmFjZSkKewogIElDT01fVEhJUyhJR2V0RnJhbWVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKCiAgaWYgKCEtLShUaGlzLT5yZWYpKSB7CiAgICBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihUaGlzKTsKICAgIGlmIChUaGlzLT5wU3RyZWFtICE9IE5VTEwpIHsKICAgICAgQVZJU3RyZWFtUmVsZWFzZShUaGlzLT5wU3RyZWFtKTsKICAgICAgVGhpcy0+cFN0cmVhbSA9IE5VTEw7CiAgICB9CgogICAgTG9jYWxGcmVlKChITE9DQUwpaWZhY2UpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gVGhpcy0+cmVmOwp9CgpzdGF0aWMgTFBWT0lEICBXSU5BUEkgSUdldEZyYW1lX2ZuR2V0RnJhbWUoSUdldEZyYW1lICppZmFjZSwgTE9ORyBsUG9zKQp7CiAgSUNPTV9USElTKElHZXRGcmFtZUltcGwsaWZhY2UpOwoKICBMT05HIHJlYWRCeXRlczsKICBMT05HIHJlYWRTYW1wbGVzOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIGlmYWNlLCBsUG9zKTsKCiAgLyogY2hlY2sgc3RhdGUgKi8KICBpZiAoVGhpcy0+cFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICAvKiBDb3VsZCBzdHJlYW0gaGF2ZSBjaGFuZ2VkPyAqLwogIGlmICghIFRoaXMtPmJGaXhlZFN0cmVhbSkgewogICAgQVZJU1RSRUFNSU5GT1cgc0luZm87CgogICAgSUFWSVN0cmVhbV9JbmZvKFRoaXMtPnBTdHJlYW0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CgogICAgaWYgKHNJbmZvLmR3RWRpdENvdW50ICE9IFRoaXMtPmR3RWRpdENvdW50KSB7CiAgICAgIFRoaXMtPmR3RWRpdENvdW50ICAgPSBzSW5mby5kd0VkaXRDb3VudDsKICAgICAgVGhpcy0+bEN1cnJlbnRGcmFtZSA9IC0xOwogICAgfQoKICAgIGlmIChzSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICE9IFRoaXMtPmR3Rm9ybWF0Q2hhbmdlQ291bnQpIHsKICAgICAgLyogc3RyZWFtIGhhcyBjaGFuZ2VkICovCiAgICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCAhPSBOVUxMKSB7CglCSVRNQVBJTkZPSEVBREVSIGJpOwoKCW1lbWNweSgmYmksIFRoaXMtPmxwT3V0Rm9ybWF0LCBzaXplb2YoYmkpKTsKCUFWSUZJTEVfQ2xvc2VDb21wcmVzc29yKFRoaXMpOwoKCWlmIChGQUlMRUQoSUdldEZyYW1lX1NldEZvcm1hdChpZmFjZSwgJmJpLCBOVUxMLCAwLCAwLCAtMSwgLTEpKSkgewoJICBpZiAoRkFJTEVEKElHZXRGcmFtZV9TZXRGb3JtYXQoaWZhY2UsIE5VTEwsIE5VTEwsIDAsIDAsIC0xLCAtMSkpKQoJICAgIHJldHVybiBOVUxMOwoJfQogICAgICB9IGVsc2UgaWYgKEZBSUxFRChJR2V0RnJhbWVfU2V0Rm9ybWF0KGlmYWNlLCBOVUxMLCBOVUxMLCAwLCAwLCAtMSwgLTEpKSkKCXJldHVybiBOVUxMOwogICAgfQogIH0KCiAgaWYgKGxQb3MgIT0gVGhpcy0+bEN1cnJlbnRGcmFtZSkgewogICAgTE9ORyBsTmV4dCA9IEFWSVN0cmVhbUZpbmRTYW1wbGUoVGhpcy0+cFN0cmVhbSwgbFBvcywgRklORF9LRVl8RklORF9QUkVWKTsKCiAgICBpZiAobE5leHQgPT0gLTEpCiAgICAgIHJldHVybiBOVUxMOwogICAgaWYgKGxOZXh0IDw9IFRoaXMtPmxDdXJyZW50RnJhbWUgJiYgVGhpcy0+bEN1cnJlbnRGcmFtZSA8IGxQb3MpCiAgICAgIGxOZXh0Kys7CgogICAgZm9yICg7IGxOZXh0IDwgbFBvczsgbE5leHQrKykgewogICAgICAvKiBuZXcgZm9ybWF0IGZvciB0aGlzIGZyYW1lPyAqLwogICAgICBpZiAoVGhpcy0+YkZvcm1hdENoYW5nZXMpIHsKCUFWSVN0cmVhbVJlYWRGb3JtYXQoVGhpcy0+cFN0cmVhbSwgbE5leHQsIFRoaXMtPmxwSW5Gb3JtYXQsICZUaGlzLT5jYkluRm9ybWF0KTsKCWlmIChUaGlzLT5scE91dEZvcm1hdCAhPSBOVUxMKSB7CgkgIGlmIChUaGlzLT5scE91dEZvcm1hdC0+YmlCaXRDb3VudCA8PSA4KQoJICAgIElDRGVjb21wcmVzc0dldFBhbGV0dGUoVGhpcy0+aGljLCBUaGlzLT5scEluRm9ybWF0LAoJCQkJICAgVGhpcy0+bHBPdXRGb3JtYXQpOwoJfQogICAgICB9CgogICAgICAvKiByZWFkIGlucHV0IGZyYW1lICovCiAgICAgIHdoaWxlIChGQUlMRUQoQVZJU3RyZWFtUmVhZChUaGlzLT5wU3RyZWFtLCBsTmV4dCwgMSwgVGhpcy0+bHBJbkJ1ZmZlciwKCQkJCSAgVGhpcy0+Y2JJbkJ1ZmZlciwgJnJlYWRCeXRlcywgJnJlYWRTYW1wbGVzKSkpIHsKCS8qIG5vdCBlbm91Z2ggbWVtb3J5IGZvciBpbnB1dCBidWZmZXI/ICovCglyZWFkQnl0ZXMgPSAwOwoJaWYgKEZBSUxFRChBVklTdHJlYW1TYW1wbGVTaXplKFRoaXMtPnBTdHJlYW0sIGxOZXh0LCAmcmVhZEJ5dGVzKSkpCgkgIHJldHVybiBOVUxMOwoJaWYgKFRoaXMtPmNiSW5CdWZmZXIgPj0gcmVhZEJ5dGVzKQoJICBicmVhazsKCVRoaXMtPmxwSW5Gb3JtYXQgPSBHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPmxwSW5Gb3JtYXQsIFRoaXMtPmNiSW5Gb3JtYXQgKyByZWFkQnl0ZXMsIDApOwoJaWYgKFRoaXMtPmxwSW5Gb3JtYXQgPT0gTlVMTCkKCSAgcmV0dXJuIE5VTEw7CglUaGlzLT5scEluQnVmZmVyID0gKEJZVEUqKVRoaXMtPmxwSW5Gb3JtYXQgKyBUaGlzLT5jYkluRm9ybWF0OwogICAgICB9CgogICAgICBpZiAocmVhZFNhbXBsZXMgIT0gMSkKCXJldHVybiBOVUxMOwogICAgICBpZiAocmVhZEJ5dGVzICE9IDApIHsKCVRoaXMtPmxwSW5Gb3JtYXQtPmJpU2l6ZUltYWdlID0gcmVhZEJ5dGVzOwoKCS8qIG5vdGhpbmcgdG8gZGVjb21wcmVzcz8gKi8KCWlmIChUaGlzLT5oaWMgPT0gTlVMTCkgewoJICBUaGlzLT5sQ3VycmVudEZyYW1lID0gbFBvczsKCSAgcmV0dXJuIFRoaXMtPmxwSW5Gb3JtYXQ7Cgl9CgoJaWYgKFRoaXMtPmJSZXNpemUpIHsKCSAgSUNEZWNvbXByZXNzRXgoVGhpcy0+aGljLDAsVGhpcy0+bHBJbkZvcm1hdCxUaGlzLT5scEluQnVmZmVyLDAsMCwKCQkJIFRoaXMtPmxwSW5Gb3JtYXQtPmJpV2lkdGgsVGhpcy0+bHBJbkZvcm1hdC0+YmlIZWlnaHQsCgkJCSBUaGlzLT5scE91dEZvcm1hdCxUaGlzLT5scE91dEJ1ZmZlcixUaGlzLT54LFRoaXMtPnksCgkJCSBUaGlzLT5keCxUaGlzLT5keSk7Cgl9IGVsc2UgewoJICBJQ0RlY29tcHJlc3MoVGhpcy0+aGljLCAwLCBUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5scEluQnVmZmVyLAoJCSAgICAgICBUaGlzLT5scE91dEZvcm1hdCwgVGhpcy0+bHBPdXRCdWZmZXIpOwoJfQogICAgICB9CiAgICB9IC8qIGZvciAobE5leHQgPCBsUG9zKSAqLwogIH0gLyogaWYgKFRoaXMtPmxDdXJyZW50RnJhbWUgIT0gbFBvcykgKi8KCiAgcmV0dXJuIChUaGlzLT5oaWMgPT0gTlVMTCA/IFRoaXMtPmxwSW5Gb3JtYXQgOiBUaGlzLT5scE91dEZvcm1hdCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJR2V0RnJhbWVfZm5CZWdpbihJR2V0RnJhbWUgKmlmYWNlLCBMT05HIGxTdGFydCwKCQkJCQlMT05HIGxFbmQsIExPTkcgbFJhdGUpCnsKICBJQ09NX1RISVMoSUdldEZyYW1lSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlbGQpXG4iLCBpZmFjZSwgbFN0YXJ0LCBsRW5kLCBsUmF0ZSk7CgogIFRoaXMtPmJGaXhlZFN0cmVhbSA9IFRSVUU7CgogIHJldHVybiAoSUdldEZyYW1lX0dldEZyYW1lKGlmYWNlLCBsU3RhcnQpID8gQVZJRVJSX09LIDogQVZJRVJSX0VSUk9SKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElHZXRGcmFtZV9mbkVuZChJR2V0RnJhbWUgKmlmYWNlKQp7CiAgSUNPTV9USElTKElHZXRGcmFtZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICBUaGlzLT5iRml4ZWRTdHJlYW0gPSBGQUxTRTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElHZXRGcmFtZV9mblNldEZvcm1hdChJR2V0RnJhbWUgKmlmYWNlLAoJCQkJCSAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaVdhbnRlZCwKCQkJCQkgICAgTFBWT0lEIGxwQml0cywgSU5UIHgsIElOVCB5LAoJCQkJCSAgICBJTlQgZHgsIElOVCBkeSkKewogIElDT01fVEhJUyhJR2V0RnJhbWVJbXBsLGlmYWNlKTsKCiAgQVZJU1RSRUFNSU5GT1cgICAgIHNJbmZvOwogIExQQklUTUFQSU5GT0hFQURFUiBscGJpICAgICAgICAgPSBscGJpV2FudGVkOwogIEJPT0wgICAgICAgICAgICAgICBiQmVzdERpc3BsYXkgPSBGQUxTRTsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlZCwlZCwlZCwlZClcbiIsIGlmYWNlLCBscGJpV2FudGVkLCBscEJpdHMsCgl4LCB5LCBkeCwgZHkpOwoKICBpZiAoVGhpcy0+cFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgaWYgKChMT05HKWxwYmlXYW50ZWQgPT0gQVZJR0VURlJBTUVGX0JFU1RESVNQTEFZRk1UKSB7CiAgICBscGJpID0gTlVMTDsKICAgIGJCZXN0RGlzcGxheSA9IFRSVUU7CiAgfQoKICBJQVZJU3RyZWFtX0luZm8oVGhpcy0+cFN0cmVhbSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKICBpZiAoc0luZm8uZmNjVHlwZSAhPSBzdHJlYW10eXBlVklERU8pCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICBUaGlzLT5iRm9ybWF0Q2hhbmdlcyA9CiAgICAoc0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUyA/IFRSVUUgOiBGQUxTRSApOwogIFRoaXMtPmR3Rm9ybWF0Q2hhbmdlQ291bnQgPSBzSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OwogIFRoaXMtPmR3RWRpdENvdW50ICAgICAgICAgPSBzSW5mby5kd0VkaXRDb3VudDsKICBUaGlzLT5sQ3VycmVudEZyYW1lICAgICAgID0gLTE7CgogIC8qIGdldCBpbnB1dCBmb3JtYXQgZnJvbSBzdHJlYW0gKi8KICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKSB7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRoaXMtPmNiSW5CdWZmZXIgPSAoTE9ORylzSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgICBpZiAoVGhpcy0+Y2JJbkJ1ZmZlciA9PSAwKQogICAgICBUaGlzLT5jYkluQnVmZmVyID0gMTAyNDsKCiAgICBBVklTdHJlYW1Gb3JtYXRTaXplKFRoaXMtPnBTdHJlYW0sIHNJbmZvLmR3U3RhcnQsICZUaGlzLT5jYkluRm9ybWF0KTsKCiAgICBUaGlzLT5scEluRm9ybWF0ID0KICAgICAgKExQQklUTUFQSU5GT0hFQURFUilHbG9iYWxBbGxvY1B0cihHSE5ELCBUaGlzLT5jYkluRm9ybWF0ICsgVGhpcy0+Y2JJbkJ1ZmZlcik7CiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKSB7CiAgICAgIEFWSUZJTEVfQ2xvc2VDb21wcmVzc29yKFRoaXMpOwogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIH0KCiAgICBociA9IEFWSVN0cmVhbVJlYWRGb3JtYXQoVGhpcy0+cFN0cmVhbSwgc0luZm8uZHdTdGFydCwgVGhpcy0+bHBJbkZvcm1hdCwgJlRoaXMtPmNiSW5Gb3JtYXQpOwogICAgaWYgKEZBSUxFRChocikpIHsKICAgICAgQVZJRklMRV9DbG9zZUNvbXByZXNzb3IoVGhpcyk7CiAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBUaGlzLT5scEluQnVmZmVyID0gKChMUEJZVEUpVGhpcy0+bHBJbkZvcm1hdCkgKyBUaGlzLT5jYkluRm9ybWF0OwogIH0KCiAgLyogY2hlY2sgaW5wdXQgZm9ybWF0ICovCiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQtPmJpQ2xyVXNlZCA9PSAwICYmIFRoaXMtPmxwSW5Gb3JtYXQtPmJpQml0Q291bnQgPD0gOCkKICAgIFRoaXMtPmxwSW5Gb3JtYXQtPmJpQ2xyVXNlZCA9IDF1IDw8IFRoaXMtPmxwSW5Gb3JtYXQtPmJpQml0Q291bnQ7CiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQtPmJpU2l6ZUltYWdlID09IDAgJiYKICAgICAgVGhpcy0+bHBJbkZvcm1hdC0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IpIHsKICAgIFRoaXMtPmxwSW5Gb3JtYXQtPmJpU2l6ZUltYWdlID0KICAgICAgRElCV0lEVEhCWVRFUygqVGhpcy0+bHBJbkZvcm1hdCkgKiBUaGlzLT5scEluRm9ybWF0LT5iaUhlaWdodDsKICB9CgogIC8qIG9ubHkgdG8gcGFzcyB0aHJvdWdoPyAqLwogIGlmIChUaGlzLT5scEluRm9ybWF0LT5iaUNvbXByZXNzaW9uID09IEJJX1JHQiAmJiBscEJpdHMgPT0gTlVMTCkgewogICAgaWYgKGxwYmkgPT0gTlVMTCB8fCAKCShscGJpLT5iaUNvbXByZXNzaW9uID09IEJJX1JHQiAmJgoJIGxwYmktPmJpV2lkdGggPT0gVGhpcy0+bHBJbkZvcm1hdC0+YmlXaWR0aCAmJgoJIGxwYmktPmJpSGVpZ2h0ID09IFRoaXMtPmxwSW5Gb3JtYXQtPmJpSGVpZ2h0ICYmCgkgbHBiaS0+YmlCaXRDb3VudCA9PSBUaGlzLT5scEluRm9ybWF0LT5iaUJpdENvdW50KSkgewogICAgICBUaGlzLT5scE91dEZvcm1hdCA9IFRoaXMtPmxwSW5Gb3JtYXQ7CiAgICAgIFRoaXMtPmxwT3V0QnVmZmVyID0gRElCUFRSKFRoaXMtPmxwSW5Gb3JtYXQpOwogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgfQogIH0KCiAgLyogbmVlZCBtZW1vcnkgZm9yIG91dHB1dCBmb3JtYXQ/ICovCiAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpIHsKICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0KICAgICAgKExQQklUTUFQSU5GT0hFQURFUilHbG9iYWxBbGxvY1B0cihHSE5ELCBzaXplb2YoQklUTUFQSU5GT0hFQURFUikKCQkJCQkgKyAyNTYgKiBzaXplb2YoUkdCUVVBRCkpOwogICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpIHsKICAgICAgQVZJRklMRV9DbG9zZUNvbXByZXNzb3IoVGhpcyk7CiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgfQogIH0KCiAgLyogbmVlZCBoYW5kbGUgdG8gdmlkZW8gY29tcHJlc3NvciAqLwogIGlmIChUaGlzLT5oaWMgPT0gTlVMTCkgewogICAgRk9VUkNDIGZjY0hhbmRsZXI7CgogICAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQtPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKQogICAgICBmY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CiAgICBlbHNlIGlmIChUaGlzLT5scEluRm9ybWF0LT5iaUNvbXByZXNzaW9uID09IEJJX1JMRTgpCiAgICAgIGZjY0hhbmRsZXIgPSBtbWlvRk9VUkNDKCdSJywnTCcsJ0UnLCcgJyk7CiAgICBlbHNlCiAgICAgIGZjY0hhbmRsZXIgPSBzSW5mby5mY2NIYW5kbGVyOwoKICAgIGlmIChscGJpICE9IE5VTEwpIHsKICAgICAgaWYgKGxwYmktPmJpV2lkdGggPT0gMCkKCWxwYmktPmJpV2lkdGggPSBUaGlzLT5scEluRm9ybWF0LT5iaVdpZHRoOwogICAgICBpZiAobHBiaS0+YmlIZWlnaHQgPT0gMCkKCWxwYmktPmJpSGVpZ2h0ID0gVGhpcy0+bHBJbkZvcm1hdC0+YmlIZWlnaHQ7CiAgICB9CgogICAgVGhpcy0+aGljID0gSUNMb2NhdGUoSUNUWVBFX1ZJREVPLCBmY2NIYW5kbGVyLCBUaGlzLT5scEluRm9ybWF0LCBscGJpLCBJQ01PREVfREVDT01QUkVTUyk7CiAgICBpZiAoVGhpcy0+aGljID09IE5VTEwpIHsKICAgICAgQVZJRklMRV9DbG9zZUNvbXByZXNzb3IoVGhpcyk7CiAgICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwogICAgfQogIH0KCiAgLyogb3V0cHV0IGZvcm1hdCBnaXZlbj8gKi8KICBpZiAobHBiaSAhPSBOVUxMKSB7CiAgICAvKiBjaGVjayB0aGUgZ2l2ZW4gb3V0cHV0IGZvcm1hdCAuLi4gKi8KICAgIGlmIChscGJpLT5iaUNsclVzZWQgPT0gMCAmJiBscGJpLT5iaUJpdENvdW50IDw9IDgpCiAgICAgIGxwYmktPmJpQ2xyVXNlZCA9IDF1IDw8IGxwYmktPmJpQml0Q291bnQ7CgogICAgLyogLi4uIGFuZCByZW1lbWJlciBpdCAqLwogICAgbWVtY3B5KFRoaXMtPmxwT3V0Rm9ybWF0LCBscGJpLAoJICAgbHBiaS0+YmlTaXplICsgbHBiaS0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpKTsKICAgIGlmIChscGJpLT5iaUJpdENvdW50IDw9IDgpCiAgICAgIElDRGVjb21wcmVzc0dldFBhbGV0dGUoVGhpcy0+aGljLCBUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5scE91dEZvcm1hdCk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UgewogICAgaWYgKGJCZXN0RGlzcGxheSkgewogICAgICBJQ0dldERpc3BsYXlGb3JtYXQoVGhpcy0+aGljLCBUaGlzLT5scEluRm9ybWF0LAoJCQkgVGhpcy0+bHBPdXRGb3JtYXQsIDAsIGR4LCBkeSk7CiAgICB9IGVsc2UgaWYgKElDRGVjb21wcmVzc0dldEZvcm1hdChUaGlzLT5oaWMsIFRoaXMtPmxwSW5Gb3JtYXQsCgkJCQkgICAgIFRoaXMtPmxwT3V0Rm9ybWF0KSA8IDApIHsKICAgICAgQVZJRklMRV9DbG9zZUNvbXByZXNzb3IoVGhpcyk7CiAgICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwogICAgfQoKICAgIC8qIGNoZWNrIG91dHB1dCBmb3JtYXQgKi8KICAgIGlmIChUaGlzLT5scE91dEZvcm1hdC0+YmlDbHJVc2VkID09IDAgJiYKCVRoaXMtPmxwT3V0Rm9ybWF0LT5iaUJpdENvdW50IDw9IDgpCiAgICAgIFRoaXMtPmxwT3V0Rm9ybWF0LT5iaUNsclVzZWQgPSAxdSA8PCBUaGlzLT5scE91dEZvcm1hdC0+YmlCaXRDb3VudDsKICAgIGlmIChUaGlzLT5scE91dEZvcm1hdC0+YmlTaXplSW1hZ2UgPT0gMCAmJgoJVGhpcy0+bHBPdXRGb3JtYXQtPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKSB7CiAgICAgIFRoaXMtPmxwT3V0Rm9ybWF0LT5iaVNpemVJbWFnZSA9CglESUJXSURUSEJZVEVTKCpUaGlzLT5scE91dEZvcm1hdCkgKiBUaGlzLT5scE91dEZvcm1hdC0+YmlIZWlnaHQ7CiAgICB9CgogICAgaWYgKGxwQml0cyA9PSBOVUxMKSB7CiAgICAgIHJlZ2lzdGVyIERXT1JEIHNpemUgPSBUaGlzLT5scE91dEZvcm1hdC0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpOwoKICAgICAgc2l6ZSArPSBUaGlzLT5scE91dEZvcm1hdC0+YmlTaXplICsgVGhpcy0+bHBPdXRGb3JtYXQtPmJpU2l6ZUltYWdlOwogICAgICBUaGlzLT5scE91dEZvcm1hdCA9CgkoTFBCSVRNQVBJTkZPSEVBREVSKUdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+bHBPdXRGb3JtYXQsIHNpemUsIEdNRU1fTU9WRUFCTEUpOwogICAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkgewoJQVZJRklMRV9DbG9zZUNvbXByZXNzb3IoVGhpcyk7CglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgfQogICAgICBUaGlzLT5scE91dEJ1ZmZlciA9IERJQlBUUihUaGlzLT5scE91dEZvcm1hdCk7CiAgICB9IGVsc2UKICAgICAgVGhpcy0+bHBPdXRCdWZmZXIgPSBscEJpdHM7CgogICAgLyogZm9yIHVzZXIgc2l6ZSB3YXMgaXJyZWxldmFudCAqLwogICAgaWYgKGR4ID09IC0xKQogICAgICBkeCA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5iaVdpZHRoOwogICAgaWYgKGR5ID09IC0xKQogICAgICBkeSA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5iaUhlaWdodDsKCiAgICAvKiBuZWVkIHRvIHJlc2l6ZT8gKi8KICAgIGlmICh4ICE9IDAgfHwgeSAhPSAwKSB7CiAgICAgIGlmIChkeSA9PSBUaGlzLT5scE91dEZvcm1hdC0+YmlIZWlnaHQgJiYKCSAgZHggPT0gVGhpcy0+bHBPdXRGb3JtYXQtPmJpV2lkdGgpCglUaGlzLT5iUmVzaXplID0gRkFMU0U7CiAgICAgIGVsc2UKCVRoaXMtPmJSZXNpemUgPSBUUlVFOwogICAgfQoKICAgIGlmIChUaGlzLT5iUmVzaXplKSB7CiAgICAgIFRoaXMtPnggID0geDsKICAgICAgVGhpcy0+eSAgPSB5OwogICAgICBUaGlzLT5keCA9IGR4OwogICAgICBUaGlzLT5keSA9IGR5OwoKICAgICAgaWYgKElDRGVjb21wcmVzc0V4QmVnaW4oVGhpcy0+aGljLDAsVGhpcy0+bHBJbkZvcm1hdCxUaGlzLT5scEluQnVmZmVyLDAsCgkJCSAgICAgIDAsVGhpcy0+bHBJbkZvcm1hdC0+YmlXaWR0aCwKCQkJICAgICAgVGhpcy0+bHBJbkZvcm1hdC0+YmlIZWlnaHQsVGhpcy0+bHBPdXRGb3JtYXQsCgkJCSAgICAgIFRoaXMtPmxwT3V0QnVmZmVyLCB4LCB5LCBkeCwgZHkpID09IElDRVJSX09LKQoJcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0gZWxzZSBpZiAoSUNEZWNvbXByZXNzQmVnaW4oVGhpcy0+aGljLCBUaGlzLT5scEluRm9ybWF0LAoJCQkJIFRoaXMtPmxwT3V0Rm9ybWF0KSA9PSBJQ0VSUl9PSykKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgICBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihUaGlzKTsKCiAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCg==