LyogIAkJCURpcmVjdFNvdW5kCiAqIAogKiBDb3B5cmlnaHQgMTk5OCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggUm9iIFJpZ2dzCiAqIENvcHlyaWdodCAyMDAwIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzLCBJbmMuCiAqLwovKgogKiBNb3N0IHRocmVhZCBsb2NraW5nIGlzIGNvbXBsZXRlLiBUaGVyZSBtYXkgYmUgYSBmZXcgcmFjZQogKiBjb25kaXRpb25zIHN0aWxsIGx1cmtpbmcuCiAqCiAqIFRlc3RlZCB3aXRoIGEgU291bmRibGFzdGVyIGNsb25lLCBhIEdyYXZpcyBVbHRyYVNvdW5kIENsYXNzaWMsCiAqIGFuZCBhIFR1cnRsZSBCZWFjaCBUcm9wZXorLgogKgogKiBUT0RPOgogKglJbXBsZW1lbnQgRGlyZWN0U291bmRDYXB0dXJlIEFQSQogKglJbXBsZW1lbnQgU2V0Q29vcGVyYXRpdmVMZXZlbCBwcm9wZXJseSAobmVlZCB0byBhZGRyZXNzIGZvY3VzIGlzc3VlcykKICoJSW1wbGVtZW50IERpcmVjdFNvdW5kM0RCdWZmZXJzIChzdHVicyBpbiBwbGFjZSkKICoJVXNlIGhhcmR3YXJlIDNEIHN1cHBvcnQgaWYgYXZhaWxhYmxlCiAqICAgICAgQWRkIGNyaXRpY2FsIHNlY3Rpb24gbG9ja2luZyBpbnNpZGUgUmVsZWFzZSBhbmQgQWRkUmVmIG1ldGhvZHMKICogICAgICBIYW5kbGUgc3RhdGljIGJ1ZmZlcnMgLSBwdXQgdGhvc2UgaW4gaGFyZHdhcmUsIG5vbi1zdGF0aWMgbm90IGluIGhhcmR3YXJlCiAqICAgICAgSGFyZHdhcmUgRHVwbGljYXRlU291bmRCdWZmZXIKICogICAgICBQcm9wZXIgdm9sdW1lIGNhbGN1bGF0aW9uLCBhbmQgc2V0dGluZyB2b2x1bWUgaW4gSEVMIHByaW1hcnkgYnVmZmVyCiAqICAgICAgT3B0aW1pemUgV0lOTU0gYW5kIG5lZ290aWF0ZSBmcmFnbWVudCBzaXplLCBkZWNyZWFzZSBEU19IRUxfTUFSR0lOCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPG1hdGguaD4JLyogSW5zb21uaWEgLSBwb3coKSBmdW5jdGlvbiAqLwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgIndpbmUvd2luZGVmMTYuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKCiNpbmNsdWRlICJpbml0Z3VpZC5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKGRzb3VuZCk7CgovKiB0aGVzZSBhcmUgZWxpZ2libGUgZm9yIHR1bmluZy4uLiB0aGV5IG11c3QgYmUgaGlnaCBvbiBzbG93IG1hY2hpbmVzLi4uICovCi8qIGVzcGVjaWFsbHkgc2luY2UgdGhlIFdJTk1NIG92ZXJoZWFkIGlzIHByZXR0eSBoaWdoLCBhbmQgY291bGQgYmUgaW1wcm92ZWQgcXVpdGUgYSBiaXQ7CiAqIHRoZSBoaWdoIERTX0hFTF9NQVJHSU4gcmVmbGVjdHMgdGhlIGN1cnJlbnRseSBoaWdoIHdpbmVvc3MvSEVMIGxhdGVuY3kKICogc29tZSBzZXR0aW5ncyBoZXJlIHNob3VsZCBwcm9iYWJseSBnZXQgcG9ydGVkIHRvIHdpbmUuY29uZiAqLwojZGVmaW5lIERTX0VNVUxEUklWRVIgMSAvKiBzb21lIGdhbWVzIChRdWFrZSAyLCBVVCkgcmVmdXNlIHRvIGFjY2VwdAoJCQkJZW11bGF0ZWQgZHNvdW5kIGRldmljZXMuIHNldCB0byAwICEgKi8gCiNkZWZpbmUgRFNfSEVMX0ZSQUdTIDQ4IC8qIEhFTCBvbmx5OiBudW1iZXIgb2Ygd2F2ZU91dCBmcmFnbWVudHMgaW4gcHJpbWFyeSBidWZmZXIgKi8KI2RlZmluZSBEU19IRUxfUVVFVUUgMjggLyogSEVMIG9ubHk6IG51bWJlciBvZiB3YXZlT3V0IGZyYWdtZW50cyB0byBwcmVidWZmZXIgKi8KCQkJLyogKFN0YXJjcmFmdCB2aWRlb3Mgd29uJ3Qgd29yayB3aXRoIGhpZ2hlciB0aGFuIDMyIHgxMG1zKSAqLwojZGVmaW5lIERTX0hFTF9NQVJHSU4gNCAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIG1peCBpbiBuZXcgYnVmZmVycyAqLwoKI2RlZmluZSBEU19IQUxfUVVFVUUgMjggLyogSEFMIG9ubHk6IG1heCBudW1iZXIgb2YgZnJhZ21lbnRzIHRvIHByZWJ1ZmZlciAqLwoKLyogTGludXggZG9lcyBub3Qgc3VwcG9ydCBiZXR0ZXIgdGltaW5nIHRoYW4gMTBtcyAqLwojZGVmaW5lIERTX1RJTUVfUkVTIDEwICAvKiBSZXNvbHV0aW9uIG9mIG11bHRpbWVkaWEgdGltZXIgKi8KI2RlZmluZSBEU19USU1FX0RFTCAxMCAgLyogRGVsYXkgb2YgbXVsdGltZWRpYSB0aW1lciBjYWxsYmFjaywgYW5kIGR1cmF0aW9uIG9mIEhFTCBmcmFnbWVudCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFByZWRlY2xhcmUgdGhlIGludGVyZmFjZSBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmVzCiAqLwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRJbXBsIElEaXJlY3RTb3VuZEltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgSURpcmVjdFNvdW5kQnVmZmVySW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kTm90aWZ5SW1wbCBJRGlyZWN0U291bmROb3RpZnlJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZCBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmRJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIC8qIElEaXJlY3RTb3VuZEltcGwgZmllbGRzICovCiAgICBQSURTRFJJVkVSICAgICAgICAgICAgICAgICAgZHJpdmVyOwogICAgRFNEUklWRVJERVNDICAgICAgICAgICAgICAgIGRydmRlc2M7CiAgICBEU0RSSVZFUkNBUFMgICAgICAgICAgICAgICAgZHJ2Y2FwczsKICAgIEhXQVZFT1VUICAgICAgICAgICAgICAgICAgICBod287CiAgICBMUFdBVkVIRFIgICAgICAgICAgICAgICAgICAgcHdhdmVbRFNfSEVMX0ZSQUdTXTsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcklELCBwd3BsYXksIHB3d3JpdGUsIHB3cXVldWU7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgZnJhZ2xlbjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBwcmlvbGV2ZWw7CiAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgbnJvZmJ1ZmZlcnM7CiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogICAgYnVmZmVyczsKICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqICAgICBwcmltYXJ5OwogICAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqIGxpc3RlbmVyOwogICAgV0FWRUZPUk1BVEVYICAgICAgICAgICAgICAgIHdmeDsgLyogY3VycmVudCBtYWluIHdhdmVmb3JtYXQgKi8KICAgIENSSVRJQ0FMX1NFQ1RJT04JCWxvY2s7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kQnVmZmVyIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmRCdWZmZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kQnVmZmVySW1wbCBmaWVsZHMgKi8KICAgIFBJRFNEUklWRVJCVUZGRVIgICAgICAgICAgaHdidWY7CiAgICBXQVZFRk9STUFURVggICAgICAgICAgICAgIHdmeDsKICAgIExQQllURSAgICAgICAgICAgICAgICAgICAgYnVmZmVyOwogICAgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsKiBkczNkYjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgcGxheWZsYWdzLHN0YXRlLGxlYWRpbjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgcGxheXBvcyxtaXhwb3Msc3RhcnRwb3Msd3JpdGVsZWFkLGJ1ZmxlbjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgbkF2Z0J5dGVzUGVyU2VjOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBmcmVxOwogICAgVUxPTkcgICAgICAgICAgICAgICAgICAgICBmcmVxQWRqdXN0OwogICAgRFNWT0xVTUVQQU4gICAgICAgICAgICAgICB2b2xwYW47CiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiAgIHBhcmVudDsgICAgICAgICAvKiBmb3IgZHVwbGljYXRlcyAqLwogICAgSURpcmVjdFNvdW5kSW1wbCogICAgICAgICBkc291bmQ7CiAgICBEU0JVRkZFUkRFU0MgICAgICAgICAgICAgIGRzYmQ7CiAgICBMUERTQlBPU0lUSU9OTk9USUZZICAgICAgIG5vdGlmaWVzOwogICAgaW50ICAgICAgICAgICAgICAgICAgICAgICBucm9mbm90aWZpZXM7CiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICAgIGxvY2s7Cn07CgojZGVmaW5lIFNUQVRFX1NUT1BQRUQgIDAKI2RlZmluZSBTVEFURV9TVEFSVElORyAxCiNkZWZpbmUgU1RBVEVfUExBWUlORyAgMgojZGVmaW5lIFNUQVRFX1NUT1BQSU5HIDMKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmROb3RpZnkgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kTm90aWZ5SW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZE5vdGlmeSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmROb3RpZnlJbXBsIGZpZWxkcyAqLwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogZHNiOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJRGlyZWN0U291bmQzRExpc3RlbmVyIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kM0RMaXN0ZW5lcik7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwgZmllbGRzICovCiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBkc2I7CiAgICBEUzNETElTVEVORVIgICAgICAgICAgICBkczNkbDsKICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7ICAgCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kM0RCdWZmZXIgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kM0RCdWZmZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmQzREJ1ZmZlckltcGwgZmllbGRzICovCiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBkc2I7CiAgICBEUzNEQlVGRkVSICAgICAgICAgICAgICBkczNkYjsKICAgIExQQllURSAgICAgICAgICAgICAgICAgIGJ1ZmZlcjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgIGJ1ZmxlbjsKICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7Cn07CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZENhcHR1cmUgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmRDYXB0dXJlKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwoKICAgIC8qIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsIGZpZWxkcyAqLwogICAgQ1JJVElDQUxfU0VDVElPTiAgICAgICAgbG9jazsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmRDYXB0dXJlIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlcik7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKCiAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCBmaWVsZHMgKi8KICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7Cn07CgoKLyogI2RlZmluZSBVU0VfRFNPVU5EM0QgMSAqLwoKI2RlZmluZSBEU09VTkRfRlJFUVNISUZUICgxNCkKCnN0YXRpYyBJRGlyZWN0U291bmRJbXBsKglkc291bmQgPSBOVUxMOwoKc3RhdGljIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqCXByaW1hcnlidWYgPSBOVUxMOwoKc3RhdGljIHZvaWQgRFNPVU5EX0NoZWNrRXZlbnQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBpbnQgbGVuKTsKCnN0YXRpYyBIUkVTVUxUIERTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmUoIExQVk9JRCogcHBvYmogKTsKc3RhdGljIEhSRVNVTFQgRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlciggTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCdWZmZXJEZXNjLCBMUFZPSUQqIHBwb2JqICk7CgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZSkgZHNjdnQ7CnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKSBkc2NidnQ7CgpzdGF0aWMgSFJFU1VMVCBtbUVycihVSU5UIGVycikKewoJc3dpdGNoKGVycikgewoJY2FzZSBNTVNZU0VSUl9OT0VSUk9SOgoJCXJldHVybiBEU19PSzsKCWNhc2UgTU1TWVNFUlJfQUxMT0NBVEVEOgoJCXJldHVybiBEU0VSUl9BTExPQ0FURUQ7CgljYXNlIE1NU1lTRVJSX0lOVkFMSEFORExFOgoJCXJldHVybiBEU0VSUl9HRU5FUklDOyAvKiBGSVhNRSAqLwoJY2FzZSBNTVNZU0VSUl9OT0RSSVZFUjoKCQlyZXR1cm4gRFNFUlJfTk9EUklWRVI7CgljYXNlIE1NU1lTRVJSX05PTUVNOgoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCWNhc2UgTU1TWVNFUlJfSU5WQUxQQVJBTToKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJZGVmYXVsdDoKCQlGSVhNRSgiVW5rbm93biBNTVNZUyBlcnJvciAlZFxuIixlcnIpOwoJCXJldHVybiBEU0VSUl9HRU5FUklDOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kRW51bWVyYXRlQSBbRFNPVU5ELjJdICAKICoKICogRW51bWVyYXRlIGFsbCBEaXJlY3RTb3VuZCBkcml2ZXJzIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfSU5WQUxJRFBBUkFNCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZEVudW1lcmF0ZUEoCglMUERTRU5VTUNBTExCQUNLQSBscERTRW51bUNhbGxiYWNrLAoJTFBWT0lEIGxwQ29udGV4dCkKewoJVFJBQ0UoImxwRFNFbnVtQ2FsbGJhY2sgPSAlcCwgbHBDb250ZXh0ID0gJXBcbiIsIAoJCWxwRFNFbnVtQ2FsbGJhY2ssIGxwQ29udGV4dCk7CgojaWZkZWYgSEFWRV9PU1MKCWlmIChscERTRW51bUNhbGxiYWNrICE9IE5VTEwpCgkJbHBEU0VudW1DYWxsYmFjayhOVUxMLCJXSU5FIERpcmVjdFNvdW5kIHVzaW5nIE9wZW4gU291bmQgU3lzdGVtIiwKCQkgICAgInNvdW5kIixscENvbnRleHQpOwojZW5kaWYKCglyZXR1cm4gRFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRFbnVtZXJhdGVXIFtEU09VTkQuM10gIAogKgogKiBFbnVtZXJhdGUgYWxsIERpcmVjdFNvdW5kIGRyaXZlcnMgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9JTlZBTElEUEFSQU0KICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kRW51bWVyYXRlVygKCUxQRFNFTlVNQ0FMTEJBQ0tXIGxwRFNFbnVtQ2FsbGJhY2ssIAoJTFBWT0lEIGxwQ29udGV4dCApCnsKICAgICAgICBGSVhNRSgibHBEU0VudW1DYWxsYmFjayA9ICVwLCBscENvbnRleHQgPSAlcDogc3R1YlxuIiwgCiAgICAgICAgICAgICAgICBscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQpOwoKICAgICAgICByZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgdm9pZCBfZHVtcF9EU0JDQVBTKERXT1JEIHhtYXNrKSB7CglzdHJ1Y3QgewoJCURXT1JECW1hc2s7CgkJY2hhcgkqbmFtZTsKCX0gZmxhZ3NbXSA9IHsKI2RlZmluZSBGRSh4KSB7IHgsICN4IH0sCgkJRkUoRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCUZFKERTQkNBUFNfU1RBVElDKQoJCUZFKERTQkNBUFNfTE9DSEFSRFdBUkUpCgkJRkUoRFNCQ0FQU19MT0NTT0ZUV0FSRSkKCQlGRShEU0JDQVBTX0NUUkwzRCkKCQlGRShEU0JDQVBTX0NUUkxGUkVRVUVOQ1kpCgkJRkUoRFNCQ0FQU19DVFJMUEFOKQoJCUZFKERTQkNBUFNfQ1RSTFZPTFVNRSkKCQlGRShEU0JDQVBTX0NUUkxQT1NJVElPTk5PVElGWSkKCQlGRShEU0JDQVBTX0NUUkxERUZBVUxUKQoJCUZFKERTQkNBUFNfQ1RSTEFMTCkKCQlGRShEU0JDQVBTX1NUSUNLWUZPQ1VTKQoJCUZFKERTQkNBUFNfR0xPQkFMRk9DVVMpCgkJRkUoRFNCQ0FQU19HRVRDVVJSRU5UUE9TSVRJT04yKQoJCUZFKERTQkNBUFNfTVVURTNEQVRNQVhESVNUQU5DRSkKI3VuZGVmIEZFCgl9OwoJaW50CWk7CgoJZm9yIChpPTA7aTxzaXplb2YoZmxhZ3MpL3NpemVvZihmbGFnc1swXSk7aSsrKQoJCWlmICgoZmxhZ3NbaV0ubWFzayAmIHhtYXNrKSA9PSBmbGFnc1tpXS5tYXNrKQoJCQlEUFJJTlRGKCIlcyAiLGZsYWdzW2ldLm5hbWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RCdWZmZXIKICovCgovKiBJVW5rbm93biBtZXRob2RzICovCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXAsJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsLGlmYWNlKTsKCVRoaXMtPnJlZisrOwoJcmV0dXJuIFRoaXMtPnJlZjsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfUmVsZWFzZShMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKCWlmKC0tVGhpcy0+cmVmKQoJCXJldHVybiBUaGlzLT5yZWY7CgoJaWYgKFRoaXMtPmRzYikKCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5kc2IpOwoKCURlbGV0ZUNyaXRpY2FsU2VjdGlvbigmVGhpcy0+bG9jayk7CgoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPmJ1ZmZlcik7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgoJcmV0dXJuIDA7Cn0KI2VuZGlmCgovKiBJRGlyZWN0U291bmQzREJ1ZmZlciBtZXRob2RzICovCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRBbGxQYXJhbWV0ZXJzKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEUzNEQlVGRkVSIGxwRHMzZEJ1ZmZlcikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldENvbmVBbmdsZXMoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUERXT1JEIGxwZHdJbnNpZGVDb25lQW5nbGUsCglMUERXT1JEIGxwZHdPdXRzaWRlQ29uZUFuZ2xlKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZU9yaWVudGF0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2Q29uZU9yaWVudGF0aW9uKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZU91dHNpZGVWb2x1bWUoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUExPTkcgbHBsQ29uZU91dHNpZGVWb2x1bWUpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNYXhEaXN0YW5jZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmTWF4RGlzdGFuY2UpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNaW5EaXN0YW5jZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmTWluRGlzdGFuY2UpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNb2RlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEV09SRCBscGR3TW9kZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2UG9zaXRpb24pCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRWZWxvY2l0eSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRDNEVkVDVE9SIGxwdlZlbG9jaXR5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0QWxsUGFyYW1ldGVycygKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQQ0RTM0RCVUZGRVIgbHBjRHMzZEJ1ZmZlciwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lQW5nbGVzKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRFdPUkQgZHdJbnNpZGVDb25lQW5nbGUsCglEV09SRCBkd091dHNpZGVDb25lQW5nbGUsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZU9yaWVudGF0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lT3V0c2lkZVZvbHVtZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxPTkcgbENvbmVPdXRzaWRlVm9sdW1lLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1heERpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgZk1heERpc3RhbmNlLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1pbkRpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgZk1pbkRpc3RhbmNlLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1vZGUoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEV09SRCBkd01vZGUsCglEV09SRCBkd0FwcGx5KQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCJtb2RlID0gJWx4XG4iLCBkd01vZGUpOwoJVGhpcy0+ZHMzZGIuZHdNb2RlID0gZHdNb2RlOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRWZWxvY2l0eSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUQzRFZBTFVFIHgsIEQzRFZBTFVFIHksIEQzRFZBTFVFIHosCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmQzREJ1ZmZlcikgZHMzZGJ2dCA9IAp7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJLyogSVVua25vd24gbWV0aG9kcyAqLwoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9SZWxlYXNlLAoJLyogSURpcmVjdFNvdW5kM0RCdWZmZXIgbWV0aG9kcyAqLwoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldEFsbFBhcmFtZXRlcnMsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZUFuZ2xlcywKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3JpZW50YXRpb24sCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZU91dHNpZGVWb2x1bWUsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0TWF4RGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0TWluRGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0TW9kZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRWZWxvY2l0eSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVBbmdsZXMsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZU9yaWVudGF0aW9uLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVPdXRzaWRlVm9sdW1lLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1heERpc3RhbmNlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1pbkRpc3RhbmNlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1vZGUsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0UG9zaXRpb24sCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0VmVsb2NpdHksCn07CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgaW50IERTT1VORF9DcmVhdGUzREJ1ZmZlcihJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBkc2IpCnsKCURXT1JECWksIHRlbXAsIGlTaXplLCBvU2l6ZSwgb2Zmc2V0OwoJTFBCWVRFCWJJYnVmLCBiT2J1ZiwgYlRidWYgPSBOVUxMOwoJTFBXT1JECXdJYnVmLCB3T2J1Ziwgd1RidWYgPSBOVUxMOwoKCS8qIEluc2lkZSBEaXJlY3RYIHNheXMgaXQncyBzdHVwaWQgYnV0IGFsbG93ZWQgKi8KCWlmIChkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMikgewoJCS8qIENvbnZlcnQgdG8gbW9ubyAqLwoJCWlmIChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgewoJCQlpU2l6ZSA9IGRzYi0+YnVmbGVuIC8gNDsKCQkJd1RidWYgPSBtYWxsb2MoZHNiLT5idWZsZW4gLyAyKTsKCQkJaWYgKHdUYnVmID09IE5VTEwpCgkJCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgkJCWZvciAoaSA9IDA7IGkgPCBpU2l6ZTsgaSsrKQoJCQkJd1RidWZbaV0gPSAoZHNiLT5idWZmZXJbaV0gKyBkc2ItPmJ1ZmZlclsoaSAqIDIpICsgMV0pIC8gMjsKCQkJd0lidWYgPSB3VGJ1ZjsKCQl9IGVsc2UgewoJCQlpU2l6ZSA9IGRzYi0+YnVmbGVuIC8gMjsKCQkJYlRidWYgPSBtYWxsb2MoZHNiLT5idWZsZW4gLyAyKTsKCQkJaWYgKGJUYnVmID09IE5VTEwpCgkJCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgkJCWZvciAoaSA9IDA7IGkgPCBpU2l6ZTsgaSsrKQoJCQkJYlRidWZbaV0gPSAoZHNiLT5idWZmZXJbaV0gKyBkc2ItPmJ1ZmZlclsoaSAqIDIpICsgMV0pIC8gMjsKCQkJYklidWYgPSBiVGJ1ZjsKCQl9Cgl9IGVsc2UgewoJCWlmIChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgewoJCQlpU2l6ZSA9IGRzYi0+YnVmbGVuIC8gMjsKCQkJd0lidWYgPSAoTFBXT1JEKSBkc2ItPmJ1ZmZlcjsKCQl9IGVsc2UgewoJCQliSWJ1ZiA9IChMUEJZVEUpIGRzYi0+YnVmZmVyOwoJCQlpU2l6ZSA9IGRzYi0+YnVmbGVuOwoJCX0KCX0KCglpZiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSB7CgkJd09idWYgPSAoTFBXT1JEKSBkc2ItPmRzM2RiLT5idWZmZXI7CgkJb1NpemUgPSBkc2ItPmRzM2RiLT5idWZsZW4gLyAyOwoJfSBlbHNlIHsKCQliT2J1ZiA9IChMUEJZVEUpIGRzYi0+ZHMzZGItPmJ1ZmZlcjsKCQlvU2l6ZSA9IGRzYi0+ZHMzZGItPmJ1ZmxlbjsKCX0KCglvZmZzZXQgPSBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWMgLyAxMDA7CQkvKiAxMG1zICovCglpZiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2ICYmIGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KQoJCWZvciAoaSA9IDA7IGkgPCBpU2l6ZTsgaSsrKSB7CgkJCXRlbXAgPSB3SWJ1ZltpXTsKCQkJaWYgKGkgPj0gb2Zmc2V0KQoJCQkJdGVtcCArPSB3SWJ1ZltpIC0gb2Zmc2V0XSA+PiA5OwoJCQllbHNlCgkJCQl0ZW1wICs9IHdJYnVmW2kgKyBpU2l6ZSAtIG9mZnNldF0gPj4gOTsKCQkJd09idWZbaSAqIDJdID0gdGVtcDsKCQkJd09idWZbKGkgKiAyKSArIDFdID0gdGVtcDsKCQl9CgllbHNlIGlmIChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCAmJiBkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KQoJCWZvciAoaSA9IDA7IGkgPCBpU2l6ZTsgaSsrKSB7CgkJCXRlbXAgPSBiSWJ1ZltpXTsKCQkJaWYgKGkgPj0gb2Zmc2V0KQoJCQkJdGVtcCArPSBiSWJ1ZltpIC0gb2Zmc2V0XSA+PiA1OwoJCQllbHNlCgkJCQl0ZW1wICs9IGJJYnVmW2kgKyBpU2l6ZSAtIG9mZnNldF0gPj4gNTsKCQkJYk9idWZbaSAqIDJdID0gdGVtcDsKCQkJYk9idWZbKGkgKiAyKSArIDFdID0gdGVtcDsKCQl9CgkKCWlmICh3VGJ1ZikKCQlmcmVlKHdUYnVmKTsKCWlmIChiVGJ1ZikKCQlmcmVlKGJUYnVmKTsKCglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBJRGlyZWN0U291bmQzRExpc3RlbmVyCiAqLwoKLyogSVVua25vd24gbWV0aG9kcyAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX0ZBSUw7Cn0KCQpzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsLGlmYWNlKTsKCVRoaXMtPnJlZisrOwoJcmV0dXJuIFRoaXMtPnJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlKQp7CglVTE9ORyB1bFJldHVybjsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGRcbiIsIFRoaXMsIFRoaXMtPnJlZik7CgoJdWxSZXR1cm4gPSAtLVRoaXMtPnJlZjsKCgkvKiBGcmVlIGFsbCByZXNvdXJjZXMgKi8KCWlmKCB1bFJldHVybiA9PSAwICkgewoJCWlmKFRoaXMtPmRzYikKCQkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+ZHNiKTsKCQlEZWxldGVDcml0aWNhbFNlY3Rpb24oJlRoaXMtPmxvY2spOwoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCX0KCglyZXR1cm4gdWxSZXR1cm47Cn0KCi8qIElEaXJlY3RTb3VuZDNETGlzdGVuZXIgbWV0aG9kcyAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0QWxsUGFyYW1ldGVyKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUERTM0RMSVNURU5FUiBscERTM0RMKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXREaXN0YW5jZUZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEM0RWQUxVRSBscGZEaXN0YW5jZUZhY3RvcikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0RG9wcGxlckZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEM0RWQUxVRSBscGZEb3BwbGVyRmFjdG9yKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRPcmllbnRhdGlvbigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2T3JpZW50RnJvbnQsCglMUEQzRFZFQ1RPUiBscHZPcmllbnRUb3ApCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUEQzRFZFQ1RPUiBscHZQb3NpdGlvbikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0Um9sbG9mZkZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEM0RWQUxVRSBscGZSb2xsb2ZmRmFjdG9yKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRWZWxvY2l0eSgKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2VmVsb2NpdHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldEFsbFBhcmFtZXRlcnMoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQQ0RTM0RMSVNURU5FUiBscGNEUzNETCwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldERpc3RhbmNlRmFjdG9yKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglEM0RWQUxVRSBmRGlzdGFuY2VGYWN0b3IsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXREb3BwbGVyRmFjdG9yKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglEM0RWQUxVRSBmRG9wcGxlckZhY3RvciwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldE9yaWVudGF0aW9uKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglEM0RWQUxVRSB4RnJvbnQsIEQzRFZBTFVFIHlGcm9udCwgRDNEVkFMVUUgekZyb250LAoJRDNEVkFMVUUgeFRvcCwgRDNEVkFMVUUgeVRvcCwgRDNEVkFMVUUgelRvcCwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglEM0RWQUxVRSB4LCBEM0RWQUxVRSB5LCBEM0RWQUxVRSB6LAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0Um9sbG9mZkZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgZlJvbGxvZmZGYWN0b3IsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRWZWxvY2l0eSgKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0NvbW1pdERlZmVycmVkU2V0dGluZ3MoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSkKCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZDNETGlzdGVuZXIpIGRzM2RsdnQgPSAKewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCS8qIElVbmtub3duIG1ldGhvZHMgKi8KCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfQWRkUmVmLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfUmVsZWFzZSwKCS8qIElEaXJlY3RTb3VuZDNETGlzdGVuZXIgbWV0aG9kcyAqLwoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0QWxsUGFyYW1ldGVyLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0RGlzdGFuY2VGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXREb3BwbGVyRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0T3JpZW50YXRpb24sCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldFJvbGxvZmZGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRWZWxvY2l0eSwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldEFsbFBhcmFtZXRlcnMsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXREaXN0YW5jZUZhY3RvciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldERvcHBsZXJGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRPcmllbnRhdGlvbiwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFBvc2l0aW9uLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0Um9sbG9mZkZhY3RvciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFZlbG9jaXR5LAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfQ29tbWl0RGVmZXJyZWRTZXR0aW5ncywKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJRGlyZWN0U291bmROb3RpZnkKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmROb3RpZnlJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORE5PVElGWSBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZE5vdGlmeUltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXAsJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZE5vdGlmeUltcGxfQWRkUmVmKExQRElSRUNUU09VTkROT1RJRlkgaWZhY2UpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmROb3RpZnlJbXBsLGlmYWNlKTsKCXJldHVybiArKyhUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZE5vdGlmeUltcGxfUmVsZWFzZShMUERJUkVDVFNPVU5ETk9USUZZIGlmYWNlKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kTm90aWZ5SW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGRcbiIsIFRoaXMsIFRoaXMtPnJlZik7CgoJVGhpcy0+cmVmLS07CglpZiAoIVRoaXMtPnJlZikgewoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKVRoaXMtPmRzYik7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwoJCXJldHVybiAwOwoJfQoJcmV0dXJuIFRoaXMtPnJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZE5vdGlmeUltcGxfU2V0Tm90aWZpY2F0aW9uUG9zaXRpb25zKAoJTFBESVJFQ1RTT1VORE5PVElGWSBpZmFjZSxEV09SRCBob3dtdWNoLExQQ0RTQlBPU0lUSU9OTk9USUZZIG5vdGlmeQopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmROb3RpZnlJbXBsLGlmYWNlKTsKCWludAlpOwoKCWlmIChUUkFDRV9PTihkc291bmQpKSB7CgkgICAgVFJBQ0UoIiglcCwweCUwOGx4LCVwKVxuIixUaGlzLGhvd211Y2gsbm90aWZ5KTsKCSAgICBmb3IgKGk9MDtpPGhvd211Y2g7aSsrKQoJCSAgICBUUkFDRSgibm90aWZ5IGF0ICVsZCB0byAweCUwOGx4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90aWZ5W2ldLmR3T2Zmc2V0LChEV09SRClub3RpZnlbaV0uaEV2ZW50Tm90aWZ5KTsKCX0KCVRoaXMtPmRzYi0+bm90aWZpZXMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksVGhpcy0+ZHNiLT5ub3RpZmllcywoVGhpcy0+ZHNiLT5ucm9mbm90aWZpZXMraG93bXVjaCkqc2l6ZW9mKERTQlBPU0lUSU9OTk9USUZZKSk7CgltZW1jcHkoCVRoaXMtPmRzYi0+bm90aWZpZXMrVGhpcy0+ZHNiLT5ucm9mbm90aWZpZXMsCgkJbm90aWZ5LAoJCWhvd211Y2gqc2l6ZW9mKERTQlBPU0lUSU9OTk9USUZZKQoJKTsKCVRoaXMtPmRzYi0+bnJvZm5vdGlmaWVzKz1ob3dtdWNoOwoKCXJldHVybiBTX09LOwp9CgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kTm90aWZ5KSBkc252dCA9IAp7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9RdWVyeUludGVyZmFjZSwKCUlEaXJlY3RTb3VuZE5vdGlmeUltcGxfQWRkUmVmLAoJSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9SZWxlYXNlLAoJSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9TZXROb3RpZmljYXRpb25Qb3NpdGlvbnMsCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSURpcmVjdFNvdW5kQnVmZmVyCiAqLwoKc3RhdGljIHZvaWQgRFNPVU5EX1JlY2FsY1ZvbFBhbihQRFNWT0xVTUVQQU4gdm9scGFuKQp7Cglkb3VibGUgdGVtcDsKCgkvKiB0aGUgQW1wRmFjdG9ycyBhcmUgZXhwcmVzc2VkIGluIDE2LjE2IGZpeGVkIHBvaW50ICovCgl2b2xwYW4tPmR3Vm9sQW1wRmFjdG9yID0gKFVMT05HKSAocG93KDIuMCwgdm9scGFuLT5sVm9sdW1lIC8gNjAwLjApICogNjU1MzYpOwoJLyogRklYTUU6IGR3UGFue0xlZnR8UmlnaHR9QW1wRmFjdG9yICovCgoJLyogRklYTUU6IHVzZSBjYWxjdWxhdGVkIHZvbCBhbmQgcGFuIGFtcGZhY3RvcnMgKi8KCXRlbXAgPSAoZG91YmxlKSAodm9scGFuLT5sVm9sdW1lIC0gKHZvbHBhbi0+bFBhbiA+IDAgPyB2b2xwYW4tPmxQYW4gOiAwKSk7Cgl2b2xwYW4tPmR3VG90YWxMZWZ0QW1wRmFjdG9yID0gKFVMT05HKSAocG93KDIuMCwgdGVtcCAvIDYwMC4wKSAqIDY1NTM2KTsKCXRlbXAgPSAoZG91YmxlKSAodm9scGFuLT5sVm9sdW1lICsgKHZvbHBhbi0+bFBhbiA8IDAgPyB2b2xwYW4tPmxQYW4gOiAwKSk7Cgl2b2xwYW4tPmR3VG90YWxSaWdodEFtcEZhY3RvciA9IChVTE9ORykgKHBvdygyLjAsIHRlbXAgLyA2MDAuMCkgKiA2NTUzNik7CgoJVFJBQ0UoImxlZnQgPSAlbHgsIHJpZ2h0ID0gJWx4XG4iLCB2b2xwYW4tPmR3VG90YWxMZWZ0QW1wRmFjdG9yLCB2b2xwYW4tPmR3VG90YWxSaWdodEFtcEZhY3Rvcik7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9SZWNhbGNGb3JtYXQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiKQp7CglEV09SRCBzdzsKCglzdyA9IGRzYi0+d2Z4Lm5DaGFubmVscyAqIChkc2ItPndmeC53Qml0c1BlclNhbXBsZSAvIDgpOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgJiYgZHNiLT5od2J1ZikgewoJCURXT1JEIGZyYWdsZW47CgkJLyogbGV0IGZyYWdtZW50IHNpemUgYXBwcm94aW1hdGUgdGhlIHRpbWVyIGRlbGF5ICovCgkJZnJhZ2xlbiA9IChkc2ItPmZyZXEgKiBEU19USU1FX0RFTCAvIDEwMDApICogc3c7CgkJLyogcmVkdWNlIGZyYWdtZW50IHNpemUgdW50aWwgYW4gaW50ZWdlciBudW1iZXIgb2YgdGhlbSBmaXRzIGluIHRoZSBidWZmZXIgKi8KCQkvKiAoRklYTUU6IHRoaXMgbWF5IG9yIG1heSBub3QgYmUgYSBnb29kIGlkZWEpICovCgkJd2hpbGUgKGRzYi0+YnVmbGVuICUgZnJhZ2xlbikgZnJhZ2xlbiAtPSBzdzsKCQlkc2ItPmRzb3VuZC0+ZnJhZ2xlbiA9IGZyYWdsZW47CgkJVFJBQ0UoImZyYWdsZW49JWxkXG4iLCBkc2ItPmRzb3VuZC0+ZnJhZ2xlbik7Cgl9CgkvKiBjYWxjdWxhdGUgdGhlIDEwbXMgd3JpdGUgbGVhZCAqLwoJZHNiLT53cml0ZWxlYWQgPSAoZHNiLT5mcmVxIC8gMTAwKSAqIHN3Owp9CgpzdGF0aWMgSFJFU1VMVCBEU09VTkRfUHJpbWFyeU9wZW4oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiKQp7CglIUkVTVUxUIGVyciA9IERTX09LOwoKCS8qIGFyZSB3ZSB1c2luZyB3YXZlT3V0IHN0dWZmPyAqLwoJaWYgKCFkc2ItPmh3YnVmKSB7CgkJTFBCWVRFIG5ld2J1ZjsKCQlEV09SRCBidWZsZW47CgkJSFJFU1VMVCBtZXJyID0gRFNfT0s7CgkJLyogU3RhcnQgaW4gcGF1c2UgbW9kZSwgdG8gYWxsb3cgYnVmZmVycyB0byBnZXQgZmlsbGVkICovCgkJd2F2ZU91dFBhdXNlKGRzYi0+ZHNvdW5kLT5od28pOwoJCS8qIHVzZSBmcmFnbWVudHMgb2YgMTBtcyAoMS8xMDBzKSBlYWNoICh3aGljaCBzaG91bGQgZ2V0IHVzIHdpdGhpbgoJCSAqIHRoZSBkb2N1bWVudGVkIHdyaXRlIGN1cnNvciBsZWFkIG9mIDEwLTE1bXMpICovCgkJYnVmbGVuID0gKChkc2ItPndmeC5uQXZnQnl0ZXNQZXJTZWMgLyAxMDApICYgfjMpICogRFNfSEVMX0ZSQUdTOwoJCVRSQUNFKCJkZXNpcmVkIGJ1Zmxlbj0lbGQsIG9sZCBidWZmZXI9JXBcbiIsIGJ1ZmxlbiwgZHNiLT5idWZmZXIpOwoJCS8qIHJlYWxsb2NhdGUgZW11bGF0ZWQgcHJpbWFyeSBidWZmZXIgKi8KCQluZXdidWYgPSAoTFBCWVRFKUhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxkc2ItPmJ1ZmZlcixidWZsZW4pOwoJCWlmIChuZXdidWYgPT0gTlVMTCkgewoJCQlFUlIoImZhaWxlZCB0byBhbGxvY2F0ZSBwcmltYXJ5IGJ1ZmZlclxuIik7CgkJCW1lcnIgPSBEU0VSUl9PVVRPRk1FTU9SWTsKCQkJLyogYnV0IHRoZSBvbGQgYnVmZmVyIG1pZ2h0IHN0aWxsIGV4aXN0cyBhbmQgbXVzdCBiZSByZS1wcmVwYXJlZCAqLwoJCX0gZWxzZSB7CgkJCWRzYi0+YnVmZmVyID0gbmV3YnVmOwoJCQlkc2ItPmJ1ZmxlbiA9IGJ1ZmxlbjsKCQl9CgkJaWYgKGRzYi0+YnVmZmVyKSB7CgkJCXVuc2lnbmVkIGM7CgkJCUlEaXJlY3RTb3VuZEltcGwgKmRzID0gZHNiLT5kc291bmQ7CgoJCQlkcy0+ZnJhZ2xlbiA9IGRzYi0+YnVmbGVuIC8gRFNfSEVMX0ZSQUdTOwoKCQkJLyogcHJlcGFyZSBmcmFnbWVudCBoZWFkZXJzICovCgkJCWZvciAoYz0wOyBjPERTX0hFTF9GUkFHUzsgYysrKSB7CgkJCQlkcy0+cHdhdmVbY10tPmxwRGF0YSA9IGRzYi0+YnVmZmVyICsgYypkcy0+ZnJhZ2xlbjsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdCdWZmZXJMZW5ndGggPSBkcy0+ZnJhZ2xlbjsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdVc2VyID0gKERXT1JEKWRzYjsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdGbGFncyA9IDA7CgkJCQlkcy0+cHdhdmVbY10tPmR3TG9vcHMgPSAwOwoJCQkJZXJyID0gbW1FcnIod2F2ZU91dFByZXBhcmVIZWFkZXIoZHMtPmh3byxkcy0+cHdhdmVbY10sc2l6ZW9mKFdBVkVIRFIpKSk7CgkJCQlpZiAoZXJyICE9IERTX09LKSB7CgkJCQkJd2hpbGUgKGMtLSkKCQkJCQkJd2F2ZU91dFVucHJlcGFyZUhlYWRlcihkcy0+aHdvLGRzLT5wd2F2ZVtjXSxzaXplb2YoV0FWRUhEUikpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCQlkcy0+cHdwbGF5ID0gMDsKCQkJZHMtPnB3d3JpdGUgPSAwOwoJCQlkcy0+cHdxdWV1ZSA9IDA7CgkJCW1lbXNldChkc2ItPmJ1ZmZlciwgKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSA/IDAgOiAxMjgsIGRzYi0+YnVmbGVuKTsKCQkJVFJBQ0UoImZyYWdsZW49JWxkXG4iLCBkcy0+ZnJhZ2xlbik7CgkJfQoJCWlmICgoZXJyID09IERTX09LKSAmJiAobWVyciAhPSBEU19PSykpCgkJCWVyciA9IG1lcnI7Cgl9CglyZXR1cm4gZXJyOwp9CgoKc3RhdGljIHZvaWQgRFNPVU5EX1ByaW1hcnlDbG9zZShJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCS8qIGFyZSB3ZSB1c2luZyB3YXZlT3V0IHN0dWZmPyAqLwoJaWYgKCFkc2ItPmh3YnVmKSB7CgkJdW5zaWduZWQgYzsKCQlJRGlyZWN0U291bmRJbXBsICpkcyA9IGRzYi0+ZHNvdW5kOwoKCQl3YXZlT3V0UmVzZXQoZHMtPmh3byk7CgkJZm9yIChjPTA7IGM8RFNfSEVMX0ZSQUdTOyBjKyspCgkJCXdhdmVPdXRVbnByZXBhcmVIZWFkZXIoZHMtPmh3bywgZHMtPnB3YXZlW2NdLCBzaXplb2YoV0FWRUhEUikpOwoJfQp9CgovKiBUaGlzIHNldHMgdGhpcyBmb3JtYXQgZm9yIHRoZSA8ZW0+UHJpbWFyeSBCdWZmZXIgT25seTwvZW0+ICovCi8qIFNlZSBmaWxlOi8vL2Nkcm9tL3NkazUyL2RvY3Mvd29yZGRvYy9kc291bmQuZG9jIHBhZ2UgMTIwICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZvcm1hdCgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBXQVZFRk9STUFURVggd2ZleAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKiBkc2I7CglIUkVTVUxUIGVyciA9IERTX09LOwoJaW50CQkJaTsKCgkvKiBMZXQncyBiZSBwZWRhbnRpYyEgKi8KCWlmICgod2ZleCA9PSBOVUxMKSB8fAoJICAgICh3ZmV4LT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkgfHwKCSAgICAod2ZleC0+bkNoYW5uZWxzIDwgMSkgfHwgKHdmZXgtPm5DaGFubmVscyA+IDIpIHx8CgkgICAgKHdmZXgtPm5TYW1wbGVzUGVyU2VjIDwgMSkgfHwKCSAgICAod2ZleC0+bkJsb2NrQWxpZ24gPCAxKSB8fCAod2ZleC0+bkNoYW5uZWxzID4gNCkgfHwKCSAgICAoKHdmZXgtPndCaXRzUGVyU2FtcGxlICE9IDgpICYmICh3ZmV4LT53Qml0c1BlclNhbXBsZSAhPSAxNikpKSB7CgkJVFJBQ0UoImZhaWxlZCBwZWRhbnRpYyBjaGVjayFcbiIpOwoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07Cgl9CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5kc291bmQtPmxvY2spKTsKCglpZiAocHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjICE9IHdmZXgtPm5TYW1wbGVzUGVyU2VjKSB7CgkJZHNiID0gZHNvdW5kLT5idWZmZXJzOwoJCWZvciAoaSA9IDA7IGkgPCBkc291bmQtPm5yb2ZidWZmZXJzOyBpKyssIGRzYisrKSB7CgkJCS8qICoqKiogKi8KCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJigoKmRzYiktPmxvY2spKTsKCgkJCSgqZHNiKS0+ZnJlcUFkanVzdCA9ICgoKmRzYiktPmZyZXEgPDwgRFNPVU5EX0ZSRVFTSElGVCkgLwoJCQkJd2ZleC0+blNhbXBsZXNQZXJTZWM7CgoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKCgqZHNiKS0+bG9jaykpOwoJCQkvKiAqKioqICovCgkJfQoJfQoKCW1lbWNweSgmKHByaW1hcnlidWYtPndmeCksIHdmZXgsIHNpemVvZihwcmltYXJ5YnVmLT53ZngpKTsKCglUUkFDRSgiKGZvcm1hdHRhZz0weCUwNHgsY2hhbnM9JWQsc2FtcGxlcmF0ZT0lbGQsIgoJCSAgICJieXRlc3BlcnNlYz0lbGQsYmxvY2thbGlnbj0lZCxiaXRzcGVyc2FtcD0lZCxjYlNpemU9JWQpXG4iLAoJCSAgIHdmZXgtPndGb3JtYXRUYWcsIHdmZXgtPm5DaGFubmVscywgd2ZleC0+blNhbXBsZXNQZXJTZWMsCgkJICAgd2ZleC0+bkF2Z0J5dGVzUGVyU2VjLCB3ZmV4LT5uQmxvY2tBbGlnbiwgCgkJICAgd2ZleC0+d0JpdHNQZXJTYW1wbGUsIHdmZXgtPmNiU2l6ZSk7CgoJcHJpbWFyeWJ1Zi0+d2Z4Lm5BdmdCeXRlc1BlclNlYyA9CgkJVGhpcy0+d2Z4Lm5TYW1wbGVzUGVyU2VjICogVGhpcy0+d2Z4Lm5CbG9ja0FsaWduOwoJaWYgKHByaW1hcnlidWYtPmRzb3VuZC0+ZHJ2ZGVzYy5kd0ZsYWdzICYgRFNEREVTQ19ET01NU1lTVEVNU0VURk9STUFUKSB7CgkJLyogRklYTUU6IGNoZWNrIGZvciBlcnJvcnMgKi8KCQlEU09VTkRfUHJpbWFyeUNsb3NlKHByaW1hcnlidWYpOwoJCXdhdmVPdXRDbG9zZShUaGlzLT5kc291bmQtPmh3byk7CgkJVGhpcy0+ZHNvdW5kLT5od28gPSAwOwogICAgICAgICAgICAgICAgd2F2ZU91dE9wZW4oJihUaGlzLT5kc291bmQtPmh3byksIFRoaXMtPmRzb3VuZC0+ZHJ2ZGVzYy5kbkRldk5vZGUsCgkJCSAgICAmKHByaW1hcnlidWYtPndmeCksIDAsIDAsIENBTExCQUNLX05VTEwgfCBXQVZFX0RJUkVDVFNPVU5EKTsKCQlEU09VTkRfUHJpbWFyeU9wZW4ocHJpbWFyeWJ1Zik7Cgl9CglpZiAocHJpbWFyeWJ1Zi0+aHdidWYpIHsKCQllcnIgPSBJRHNEcml2ZXJCdWZmZXJfU2V0Rm9ybWF0KHByaW1hcnlidWYtPmh3YnVmLCAmKHByaW1hcnlidWYtPndmeCkpOwoJCWlmIChlcnIgPT0gRFNFUlJfQlVGRkVSTE9TVCkgewoJCQkvKiBXaW5lLW9ubHk6IHRoZSBkcml2ZXIgd2FudHMgdXMgdG8gcmVjcmVhdGUgdGhlIEhXIGJ1ZmZlciAqLwoJCQlJRHNEcml2ZXJCdWZmZXJfUmVsZWFzZShwcmltYXJ5YnVmLT5od2J1Zik7CgkJCWVyciA9IElEc0RyaXZlcl9DcmVhdGVTb3VuZEJ1ZmZlcihwcmltYXJ5YnVmLT5kc291bmQtPmRyaXZlciwmKHByaW1hcnlidWYtPndmeCkscHJpbWFyeWJ1Zi0+ZHNiZC5kd0ZsYWdzLDAsCgkJCQkJCQkgICYocHJpbWFyeWJ1Zi0+YnVmbGVuKSwmKHByaW1hcnlidWYtPmJ1ZmZlciksCgkJCQkJCQkgIChMUFZPSUQpJihwcmltYXJ5YnVmLT5od2J1ZikpOwoJCX0KCX0KCURTT1VORF9SZWNhbGNGb3JtYXQocHJpbWFyeWJ1Zik7CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5kc291bmQtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldFZvbHVtZSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTE9ORyB2b2wKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlbGQpXG4iLFRoaXMsdm9sKTsKCgkvKiBJJ20gbm90IHN1cmUgaWYgd2UgbmVlZCB0aGlzIGZvciBwcmltYXJ5IGJ1ZmZlciAqLwoJaWYgKCEoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMVk9MVU1FKSkKCQlyZXR1cm4gRFNFUlJfQ09OVFJPTFVOQVZBSUw7CgoJaWYgKCh2b2wgPiBEU0JWT0xVTUVfTUFYKSB8fCAodm9sIDwgRFNCVk9MVU1FX01JTikpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkvKiAqKioqICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglUaGlzLT52b2xwYW4ubFZvbHVtZSA9IHZvbDsKCglEU09VTkRfUmVjYWxjVm9sUGFuKCYoVGhpcy0+dm9scGFuKSk7CgoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1NldFZvbHVtZVBhbihUaGlzLT5od2J1ZiwgJihUaGlzLT52b2xwYW4pKTsKCX0KCWVsc2UgaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgewojaWYgMCAvKiBzaG91bGQgd2UgcmVhbGx5IGRvIHRoaXM/ICovCgkJLyogdGhlIERTIHZvbHVtZSByYW5nZXMgZnJvbSAwIChtYXgsIDBkQiBhdHRlbnVhdGlvbikgdG8gLTEwMDAwIChtaW4sIDEwMGRCIGF0dGVudWF0aW9uKSAqLwoJCS8qIHRoZSBNTSB2b2x1bWUgcmFuZ2VzIGZyb20gMCB0byAweGZmZmYgaW4gYW4gdW5zcGVjaWZpZWQgbG9nYXJpdGhtaWMgc2NhbGUgKi8KCQlXT1JEIGN2b2wgPSAweGZmZmYgKyB2b2wqNiArIHZvbC8yOwoJCURXT1JEIHZvbCA9IGN2b2wgfCAoKERXT1JEKWN2b2wgPDwgMTYpCgkJd2F2ZU91dFNldFZvbHVtZShUaGlzLT5kc291bmQtPmh3bywgdm9sKTsKI2VuZGlmCgl9CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiAqKioqICovCgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRWb2x1bWUoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQTE9ORyB2b2wKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwKVxuIixUaGlzLHZvbCk7CgoJaWYgKHZvbCA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJKnZvbCA9IFRoaXMtPnZvbHBhbi5sVm9sdW1lOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRGcmVxdWVuY3koCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIGZyZXEKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyxmcmVxKTsKCgkvKiBZb3UgY2Fubm90IHNldCB0aGUgZnJlcXVlbmN5IG9mIHRoZSBwcmltYXJ5IGJ1ZmZlciAqLwoJaWYgKCEoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMRlJFUVVFTkNZKSB8fAoJICAgIChUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpKQoJCXJldHVybiBEU0VSUl9DT05UUk9MVU5BVkFJTDsKCglpZiAoIWZyZXEpIGZyZXEgPSBUaGlzLT53ZngublNhbXBsZXNQZXJTZWM7CgoJaWYgKChmcmVxIDwgRFNCRlJFUVVFTkNZX01JTikgfHwgKGZyZXEgPiBEU0JGUkVRVUVOQ1lfTUFYKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPmZyZXEgPSBmcmVxOwoJVGhpcy0+ZnJlcUFkanVzdCA9IChmcmVxIDw8IERTT1VORF9GUkVRU0hJRlQpIC8gcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjOwoJVGhpcy0+bkF2Z0J5dGVzUGVyU2VjID0gZnJlcSAqIFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKCURTT1VORF9SZWNhbGNGb3JtYXQoVGhpcyk7CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiAqKioqICovCgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9QbGF5KAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxEV09SRCByZXNlcnZlZDEsRFdPUkQgcmVzZXJ2ZWQyLERXT1JEIGZsYWdzCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlMDhseCwlMDhseCwlMDhseClcbiIsCgkJVGhpcyxyZXNlcnZlZDEscmVzZXJ2ZWQyLGZsYWdzCgkpOwoJVGhpcy0+cGxheWZsYWdzID0gZmxhZ3M7CglpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCVRoaXMtPmxlYWRpbiA9IFRSVUU7CgkJVGhpcy0+c3RhcnRwb3MgPSBUaGlzLT5taXhwb3M7CgkJVGhpcy0+c3RhdGUgPSBTVEFURV9TVEFSVElORzsKCX0gZWxzZSBpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpCgkJVGhpcy0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJaWYgKCEoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9QbGF5KFRoaXMtPmh3YnVmLCAwLCAwLCBUaGlzLT5wbGF5ZmxhZ3MpOwoJCVRoaXMtPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCX0KCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU3RvcChMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKVxuIixUaGlzKTsKCgkvKiAqKioqICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJZWxzZSBpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpCgkJVGhpcy0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJaWYgKCEoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9TdG9wKFRoaXMtPmh3YnVmKTsKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7Cgl9CglEU09VTkRfQ2hlY2tFdmVudChUaGlzLCAwKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBEV09SRCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRFdPUkQgcmVmOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkLCB0aHJlYWQgaXMgJWx4XG4iLFRoaXMsIFRoaXMtPnJlZiwgR2V0Q3VycmVudFRocmVhZElkKCkpOwoKCXJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCYoVGhpcy0+cmVmKSk7CglpZiAoIXJlZikgewoJCUZJWE1FKCJ0aHJlYWQtc2FmZXR5IGFsZXJ0ISBBZGRSZWYtaW5nIHdpdGggYSB6ZXJvIHJlZmNvdW50IVxuIik7Cgl9CglyZXR1cm4gcmVmOwp9CnN0YXRpYyBEV09SRCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCWludAlpOwoJRFdPUkQgcmVmOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkLCB0aHJlYWQgaXMgJWx4XG4iLFRoaXMsIFRoaXMtPnJlZiwgR2V0Q3VycmVudFRocmVhZElkKCkpOwoKCXJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCYoVGhpcy0+cmVmKSk7CglpZiAocmVmKSByZXR1cm4gcmVmOwoKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7Cglmb3IgKGk9MDtpPFRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnM7aSsrKQoJCWlmIChUaGlzLT5kc291bmQtPmJ1ZmZlcnNbaV0gPT0gVGhpcykKCQkJYnJlYWs7CgoJaWYgKGkgPCBUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzKSB7CgkJLyogUHV0IHRoZSBsYXN0IGJ1ZmZlciBvZiB0aGUgbGlzdCBpbiB0aGUgKG5vdyBlbXB0eSkgcG9zaXRpb24gKi8KCQlUaGlzLT5kc291bmQtPmJ1ZmZlcnNbaV0gPSBUaGlzLT5kc291bmQtPmJ1ZmZlcnNbVGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycyAtIDFdOwoJCVRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnMtLTsKCQlUaGlzLT5kc291bmQtPmJ1ZmZlcnMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+ZHNvdW5kLT5idWZmZXJzLHNpemVvZihMUERJUkVDVFNPVU5EQlVGRkVSKSpUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzKTsKCQlUUkFDRSgiYnVmZmVyIGNvdW50IGlzIG5vdyAlZFxuIiwgVGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycyk7CgkJSURpcmVjdFNvdW5kX1JlbGVhc2UoKExQRElSRUNUU09VTkQpVGhpcy0+ZHNvdW5kKTsKCX0KCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7CgoJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikKCQlEU09VTkRfUHJpbWFyeUNsb3NlKFRoaXMpOwoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1JlbGVhc2UoVGhpcy0+aHdidWYpOwoJfQoJaWYgKFRoaXMtPmRzM2RiKQoJCUlEaXJlY3RTb3VuZDNEQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkQzREJVRkZFUilUaGlzLT5kczNkYik7CglpZiAoVGhpcy0+cGFyZW50KQoJCS8qIHRoaXMgaXMgYSBkdXBsaWNhdGUgYnVmZmVyICovCgkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+cGFyZW50KTsKCWVsc2UKCQkvKiB0aGlzIGlzIGEgdG9wbGV2ZWwgYnVmZmVyICovCgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPmJ1ZmZlcik7CgoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwoJCglpZiAoVGhpcyA9PSBwcmltYXJ5YnVmKQoJCXByaW1hcnlidWYgPSBOVUxMOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRDdXJyZW50UG9zaXRpb24oCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQRFdPUkQgcGxheXBvcyxMUERXT1JEIHdyaXRlcG9zCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcCwlcClcbiIsVGhpcyxwbGF5cG9zLHdyaXRlcG9zKTsKCWlmIChUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9HZXRQb3NpdGlvbihUaGlzLT5od2J1ZiwgcGxheXBvcywgd3JpdGVwb3MpOwoJfQoJZWxzZSBpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CgkJaWYgKHBsYXlwb3MgJiYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfR0VUQ1VSUkVOVFBPU0lUSU9OMikpIHsKCQkJTU1USU1FIG10aW1lOwoJCQltdGltZS53VHlwZSA9IFRJTUVfQllURVM7CgkJCXdhdmVPdXRHZXRQb3NpdGlvbihUaGlzLT5kc291bmQtPmh3bywgJm10aW1lLCBzaXplb2YobXRpbWUpKTsKCQkJbXRpbWUudS5jYiA9IG10aW1lLnUuY2IgJSBUaGlzLT5idWZsZW47CgkJCSpwbGF5cG9zID0gbXRpbWUudS5jYjsKCQl9CgkJLyogZG9uJ3Qga25vdyBob3cgZXhhY3RseSBub24tR0VUQ1VSUkVOVFBPU0lUSU9OMiBiZWhhdmVzLAoJCSAqIGJ1dCBJIHRoaW5rIHRoaXMgd29ya3MgZm9yIFN0YXJjcmFmdCAqLwoJCWVsc2UgaWYgKHBsYXlwb3MpICpwbGF5cG9zID0gVGhpcy0+cGxheXBvczsKCQlpZiAod3JpdGVwb3MpIHsKCQkJLyogdGhlIHdyaXRlcG9zIHNob3VsZCBvbmx5IGJlIHVzZWQgYnkgYXBwcyB3aXRoIFdSSVRFUFJJTUFSWSBwcmlvcml0eSwKCQkJICogaW4gd2hpY2ggY2FzZSBvdXIgc29mdHdhcmUgbWl4ZXIgaXMgZGlzYWJsZWQgYW55d2F5ICovCgkJCSp3cml0ZXBvcyA9IFRoaXMtPnBsYXlwb3MgKyBEU19IRUxfTUFSR0lOICogVGhpcy0+ZHNvdW5kLT5mcmFnbGVuOwoJCQl3aGlsZSAoKndyaXRlcG9zID49IFRoaXMtPmJ1ZmxlbikKCQkJCSp3cml0ZXBvcyAtPSBUaGlzLT5idWZsZW47CgkJfQoJfSBlbHNlIHsKCQlpZiAocGxheXBvcyAmJiAoVGhpcy0+c3RhdGUgIT0gU1RBVEVfUExBWUlORykpIHsKCQkJLyogd2UgaGF2ZW4ndCBiZWVuIG1lcmdlZCBpbnRvIHRoZSBwcmltYXJ5IGJ1ZmZlciAoeWV0KSAqLwoJCQkqcGxheXBvcyA9IFRoaXMtPm1peHBvczsKCQl9CgkJZWxzZSBpZiAocGxheXBvcykgewoJCQlEV09SRCBwcGxheSwgbHBsYXksIHNwbGF5LCB0cGxheSwgcHN0YXRlOwoJCQkvKiBsZXQncyBnZXQgdGhpcyBleGFjdDsgZmlyc3QsIHJlY3Vyc2l2ZWx5IGNhbGwgR2V0UG9zaXRpb24gb24gdGhlIHByaW1hcnkgKi8KCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJCWlmICgoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19HRVRDVVJSRU5UUE9TSVRJT04yKSB8fCBwcmltYXJ5YnVmLT5od2J1ZikgewoJCQkJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRDdXJyZW50UG9zaXRpb24oKExQRElSRUNUU09VTkRCVUZGRVIpcHJpbWFyeWJ1ZiwgJnBwbGF5LCBOVUxMKTsKCQkJfSBlbHNlIHsKCQkJCS8qICh1bmxlc3MgdGhlIGFwcCBpc24ndCB1c2luZyBHRVRDVVJSRU5UUE9TSVRJT04yKSAqLwoJCQkJLyogZG9uJ3Qga25vdyBleGFjdGx5IGhvdyB0aGlzIHNob3VsZCBiZSBoYW5kbGVkIGVpdGhlciAqLwoJCQkJcHBsYXkgPSBwcmltYXJ5YnVmLT5wbGF5cG9zOwoJCQl9CgkJCS8qIGdldCBsYXN0IG1peGVkIHByaW1hcnkgcGxheSBwb3NpdGlvbiAqLwoJCQlscGxheSA9IHByaW1hcnlidWYtPm1peHBvczsKCQkJcHN0YXRlID0gcHJpbWFyeWJ1Zi0+c3RhdGU7CgkJCS8qIGRldGVjdCBIRUwgbW9kZSB1bmRlcnJ1biAqLwoJCQlpZiAoIShwcmltYXJ5YnVmLT5od2J1ZiB8fCBwcmltYXJ5YnVmLT5kc291bmQtPnB3cXVldWUpKSB7CgkJCQlUUkFDRSgiZGV0ZWN0ZWQgYW4gdW5kZXJydW5cbiIpOwoJCQkJcHBsYXkgPSBscGxheTsKCQkJCWlmIChwc3RhdGUgPT0gU1RBVEVfUExBWUlORykKCQkJCQlwc3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJCWVsc2UgaWYgKHBzdGF0ZSA9PSBTVEFURV9TVE9QUElORykKCQkJCQlwc3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJCS8qIGdldCBvdXIgb3duIGxhc3QgbWl4ZWQgcG9zaXRpb24gd2hpbGUgd2Ugc3RpbGwgaGF2ZSB0aGUgbG9jayAqLwoJCQlzcGxheSA9IFRoaXMtPm1peHBvczsKCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJCVRSQUNFKCJwcmltYXJ5IHBsYXlwb3M9JWxkLCBtaXhwb3M9JWxkXG4iLCBwcGxheSwgbHBsYXkpOwoJCQlUUkFDRSgidGhpcyBtaXhwb3M9JWxkXG4iLCBzcGxheSk7CgoJCQkvKiB0aGUgYWN0dWFsIHByaW1hcnkgcGxheSBwb3NpdGlvbiAocHBsYXkpIGlzIGFsd2F5cyBiZWhpbmQgbGFzdCBtaXhlZCAobHBsYXkpLAoJCQkgKiB1bmxlc3MgdGhlIGNvbXB1dGVyIGlzIHRvbyBzbG93IG9yIHNvbWV0aGluZyAqLwoJCQkvKiB3ZSBuZWVkIHRvIGtub3cgaG93IGZhciBhd2F5IHdlIGFyZSBmcm9tIHRoZXJlICovCgkJCWlmIChscGxheSA9PSBwcGxheSkgewoJCQkJaWYgKChwc3RhdGUgPT0gU1RBVEVfUExBWUlORykgfHwgKHBzdGF0ZSA9PSBTVEFURV9TVE9QUElORykpIHsKCQkJCQkvKiB3b3csIHRoZSBzb2Z0d2FyZSBtaXhlciBpcyByZWFsbHkgZG9pbmcgd2VsbCwKCQkJCQkgKiBzZWVtcyB0aGUgZW50aXJlIHByaW1hcnkgYnVmZmVyIGlzIGZpbGxlZCEgKi8KCQkJCQlscGxheSArPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCQl9CgkJCQkvKiBlbHNlOiB0aGUgcHJpbWFyeSBidWZmZXIgaXMgbm90IHBsYXlpbmcsIHNvIHByb2JhYmx5IGVtcHR5ICovCgkJCX0KCQkJaWYgKGxwbGF5IDwgcHBsYXkpIGxwbGF5ICs9IHByaW1hcnlidWYtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJCQlscGxheSAtPSBwcGxheTsKCQkJLyogZGV0ZWN0IEhBTCBtb2RlIHVuZGVycnVuICovCgkJCWlmIChwcmltYXJ5YnVmLT5od2J1ZiAmJgoJCQkgICAgKGxwbGF5ID4gKChEU19IQUxfUVVFVUUgKyAxKSAqIHByaW1hcnlidWYtPmRzb3VuZC0+ZnJhZ2xlbiArIHByaW1hcnlidWYtPndyaXRlbGVhZCkpKSB7CgkJCQlUUkFDRSgiZGV0ZWN0ZWQgYW4gdW5kZXJydW46IHByaW1hcnkgcXVldWUgd2FzICVsZFxuIixscGxheSk7CgkJCQlscGxheSA9IDA7CgkJCX0KCQkJLyogZGl2aWRlIHRoZSBvZmZzZXQgYnkgaXRzIHNhbXBsZSBzaXplICovCgkJCWxwbGF5IC89IHByaW1hcnlidWYtPndmeC5uQ2hhbm5lbHMgKiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlIC8gOCk7CgkJCVRSQUNFKCJwcmltYXJ5IGJhY2stc2FtcGxlcz0lbGRcbiIsbHBsYXkpOwoJCQkvKiBhZGp1c3QgZm9yIG91ciBmcmVxdWVuY3kgKi8KCQkJbHBsYXkgPSAobHBsYXkgKiBUaGlzLT5mcmVxQWRqdXN0KSA+PiBEU09VTkRfRlJFUVNISUZUOwoJCQkvKiBtdWx0aXBseSBieSBvdXIgb3duIHNhbXBsZSBzaXplICovCgkJCWxwbGF5ICo9IFRoaXMtPndmeC5uQ2hhbm5lbHMgKiAoVGhpcy0+d2Z4LndCaXRzUGVyU2FtcGxlIC8gOCk7CgkJCVRSQUNFKCJ0aGlzIGJhY2stb2Zmc2V0PSVsZFxuIiwgbHBsYXkpOwoJCQkvKiBzdWJ0cmFjdCBmcm9tIG91ciBsYXN0IG1peGVkIHBvc2l0aW9uICovCgkJCXRwbGF5ID0gc3BsYXk7CgkJCXdoaWxlICh0cGxheSA8IGxwbGF5KSB0cGxheSArPSBUaGlzLT5idWZsZW47IC8qIHdyYXBhcm91bmQgKi8KCQkJdHBsYXkgLT0gbHBsYXk7CgkJCWlmIChUaGlzLT5sZWFkaW4gJiYgKCh0cGxheSA8IFRoaXMtPnN0YXJ0cG9zKSB8fCAodHBsYXkgPiBzcGxheSkpKSB7CgkJCQkvKiBzZWVtcyB3ZSBoYXZlbid0IHN0YXJ0ZWQgcGxheWluZyB5ZXQgKi8KCQkJCVRSQUNFKCJ0aGlzIHN0aWxsIGluIGxlYWQtaW4gcGhhc2VcbiIpOwoJCQkJdHBsYXkgPSBUaGlzLT5zdGFydHBvczsKCQkJfQoJCQkvKiByZXR1cm4gdGhlIHJlc3VsdCAqLwoJCQkqcGxheXBvcyA9IHRwbGF5OwoJCX0KCQlpZiAod3JpdGVwb3MpICp3cml0ZXBvcyA9IFRoaXMtPm1peHBvczsKCX0KCWlmICh3cml0ZXBvcykgewoJCWlmIChUaGlzLT5zdGF0ZSAhPSBTVEFURV9TVE9QUEVEKQoJCQkvKiBhcHBseSB0aGUgZG9jdW1lbnRlZCAxMG1zIGxlYWQgdG8gd3JpdGVwb3MgKi8KCQkJKndyaXRlcG9zICs9IFRoaXMtPndyaXRlbGVhZDsKCQl3aGlsZSAoKndyaXRlcG9zID49IFRoaXMtPmJ1ZmxlbikgKndyaXRlcG9zIC09IFRoaXMtPmJ1ZmxlbjsKCX0KCVRSQUNFKCJwbGF5cG9zID0gJWxkLCB3cml0ZXBvcyA9ICVsZCAoJXAsIHRpbWU9JWxkKVxuIiwgcGxheXBvcz8qcGxheXBvczowLCB3cml0ZXBvcz8qd3JpdGVwb3M6MCwgVGhpcywgR2V0VGlja0NvdW50KCkpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRTdGF0dXMoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQRFdPUkQgc3RhdHVzCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcCksIHRocmVhZCBpcyAlbHhcbiIsVGhpcyxzdGF0dXMsR2V0Q3VycmVudFRocmVhZElkKCkpOwoKCWlmIChzdGF0dXMgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCSpzdGF0dXMgPSAwOwoJaWYgKChUaGlzLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgfHwgKFRoaXMtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpKQoJCSpzdGF0dXMgfD0gRFNCU1RBVFVTX1BMQVlJTkc7CglpZiAoVGhpcy0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKQoJCSpzdGF0dXMgfD0gRFNCU1RBVFVTX0xPT1BJTkc7CgoJVFJBQ0UoInN0YXR1cz0lbHhcbiIsICpzdGF0dXMpOwoJcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Rm9ybWF0KAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUFdBVkVGT1JNQVRFWCBscHdmLERXT1JEIHdmc2l6ZSxMUERXT1JEIHdmd3JpdHRlbgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXAsJWxkLCVwKVxuIixUaGlzLGxwd2Ysd2ZzaXplLHdmd3JpdHRlbik7CgoJaWYgKHdmc2l6ZT5zaXplb2YoVGhpcy0+d2Z4KSkKCQl3ZnNpemUgPSBzaXplb2YoVGhpcy0+d2Z4KTsKCWlmIChscHdmKSB7CS8qIE5VTEwgaXMgdmFsaWQgKi8KCQltZW1jcHkobHB3ZiwmKFRoaXMtPndmeCksd2ZzaXplKTsKCQlpZiAod2Z3cml0dGVuKQoJCQkqd2Z3cml0dGVuID0gd2ZzaXplOwoJfSBlbHNlCgkJaWYgKHdmd3JpdHRlbikKCQkJKndmd3JpdHRlbiA9IHNpemVvZihUaGlzLT53ZngpOwoJCWVsc2UKCQkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0xvY2soCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIHdyaXRlY3Vyc29yLERXT1JEIHdyaXRlYnl0ZXMsTFBWT0lEIGxwbHBhdWRpb3B0cjEsTFBEV09SRCBhdWRpb2J5dGVzMSxMUFZPSUQgbHBscGF1ZGlvcHRyMixMUERXT1JEIGF1ZGlvYnl0ZXMyLERXT1JEIGZsYWdzCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRFdPUkQgY2FwZjsKCglUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJXAsJXAsJXAsMHglMDhseClcbiIsCgkJVGhpcywKCQl3cml0ZWN1cnNvciwKCQl3cml0ZWJ5dGVzLAoJCWxwbHBhdWRpb3B0cjEsCgkJYXVkaW9ieXRlczEsCgkJbHBscGF1ZGlvcHRyMiwKCQlhdWRpb2J5dGVzMiwKCQlmbGFncwoJKTsKCglpZiAoZmxhZ3MgJiBEU0JMT0NLX0ZST01XUklURUNVUlNPUikgewoJCURXT1JEIHdyaXRlcG9zOwoJCS8qIEdldEN1cnJlbnRQb3NpdGlvbiBkb2VzIHRvbyBtdWNoIG1hZ2ljIHRvIGR1cGxpY2F0ZSBoZXJlICovCgkJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRDdXJyZW50UG9zaXRpb24oaWZhY2UsIE5VTEwsICZ3cml0ZXBvcyk7CgkJd3JpdGVjdXJzb3IgKz0gd3JpdGVwb3M7Cgl9CglpZiAoZmxhZ3MgJiBEU0JMT0NLX0VOVElSRUJVRkZFUikKCQl3cml0ZWJ5dGVzID0gVGhpcy0+YnVmbGVuOwoJaWYgKHdyaXRlYnl0ZXMgPiBUaGlzLT5idWZsZW4pCgkJd3JpdGVieXRlcyA9IFRoaXMtPmJ1ZmxlbjsKCglhc3NlcnQoYXVkaW9ieXRlczEhPWF1ZGlvYnl0ZXMyKTsKCWFzc2VydChscGxwYXVkaW9wdHIxIT1scGxwYXVkaW9wdHIyKTsKCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCWNhcGYgPSBEU0RERVNDX0RPTlRORUVEUFJJTUFSWUxPQ0s7CgllbHNlCgkJY2FwZiA9IERTRERFU0NfRE9OVE5FRURTRUNPTkRBUllMT0NLOwoJaWYgKCEoVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBjYXBmKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9Mb2NrKFRoaXMtPmh3YnVmLAoJCQkJICAgICBscGxwYXVkaW9wdHIxLCBhdWRpb2J5dGVzMSwKCQkJCSAgICAgbHBscGF1ZGlvcHRyMiwgYXVkaW9ieXRlczIsCgkJCQkgICAgIHdyaXRlY3Vyc29yLCB3cml0ZWJ5dGVzLAoJCQkJICAgICAwKTsKCX0gZWxzZQoJaWYgKHdyaXRlY3Vyc29yK3dyaXRlYnl0ZXMgPD0gVGhpcy0+YnVmbGVuKSB7CgkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjEgPSBUaGlzLT5idWZmZXIrd3JpdGVjdXJzb3I7CgkJKmF1ZGlvYnl0ZXMxID0gd3JpdGVieXRlczsKCQlpZiAobHBscGF1ZGlvcHRyMikKCQkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjIgPSBOVUxMOwoJCWlmIChhdWRpb2J5dGVzMikKCQkJKmF1ZGlvYnl0ZXMyID0gMDsKCQlUUkFDRSgiLT4lbGQuMFxuIix3cml0ZWJ5dGVzKTsKCX0gZWxzZSB7CgkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjEgPSBUaGlzLT5idWZmZXIrd3JpdGVjdXJzb3I7CgkJKmF1ZGlvYnl0ZXMxID0gVGhpcy0+YnVmbGVuLXdyaXRlY3Vyc29yOwoJCWlmIChscGxwYXVkaW9wdHIyKQoJCQkqKExQQllURSopbHBscGF1ZGlvcHRyMiA9IFRoaXMtPmJ1ZmZlcjsKCQlpZiAoYXVkaW9ieXRlczIpCgkJCSphdWRpb2J5dGVzMiA9IHdyaXRlYnl0ZXMtKFRoaXMtPmJ1Zmxlbi13cml0ZWN1cnNvcik7CgkJVFJBQ0UoIi0+JWxkLiVsZFxuIiwqYXVkaW9ieXRlczEsYXVkaW9ieXRlczI/KmF1ZGlvYnl0ZXMyOjApOwoJfQoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRDdXJyZW50UG9zaXRpb24oCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIG5ld3BvcwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJWxkKVxuIixUaGlzLG5ld3Bvcyk7CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgoJVGhpcy0+bWl4cG9zID0gbmV3cG9zOwoJaWYgKFRoaXMtPmh3YnVmKQoJCUlEc0RyaXZlckJ1ZmZlcl9TZXRQb3NpdGlvbihUaGlzLT5od2J1ZiwgVGhpcy0+bWl4cG9zKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldFBhbigKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTE9ORyBwYW4KKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlbGQpXG4iLFRoaXMscGFuKTsKCglpZiAoKHBhbiA+IERTQlBBTl9SSUdIVCkgfHwgKHBhbiA8IERTQlBBTl9MRUZUKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qIFlvdSBjYW5ub3Qgc2V0IHRoZSBwYW4gb2YgdGhlIHByaW1hcnkgYnVmZmVyICovCgkvKiBhbmQgeW91IGNhbm5vdCB1c2UgYm90aCBwYW4gYW5kIDNEIGNvbnRyb2xzICovCglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQQU4pIHx8CgkgICAgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSB8fAoJICAgIChUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpKQoJCXJldHVybiBEU0VSUl9DT05UUk9MVU5BVkFJTDsKCgkvKiAqKioqICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglUaGlzLT52b2xwYW4ubFBhbiA9IHBhbjsKCglEU09VTkRfUmVjYWxjVm9sUGFuKCYoVGhpcy0+dm9scGFuKSk7CgoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1NldFZvbHVtZVBhbihUaGlzLT5od2J1ZiwgJihUaGlzLT52b2xwYW4pKTsKCX0KCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFBhbigKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBMT05HIHBhbgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXApXG4iLFRoaXMscGFuKTsKCglpZiAocGFuID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqcGFuID0gVGhpcy0+dm9scGFuLmxQYW47CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9VbmxvY2soCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQVk9JRCBwMSxEV09SRCB4MSxMUFZPSUQgcDIsRFdPUkQgeDIKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglEV09SRCBjYXBmOwoKCVRSQUNFKCIoJXAsJXAsJWxkLCVwLCVsZCk6c3R1YlxuIiwgVGhpcyxwMSx4MSxwMix4Mik7CgojaWYgMAoJLyogUHJlcHJvY2VzcyAzRCBidWZmZXJzLi4uICovCgoJLyogVGhpcyBpcyBoaWdobHkgZXhwZXJpbWVudGFsIGFuZCBsaWFibGUgdG8gYnJlYWsgdGhpbmdzICovCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpCgkJRFNPVU5EX0NyZWF0ZTNEQnVmZmVyKFRoaXMpOwojZW5kaWYKCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCWNhcGYgPSBEU0RERVNDX0RPTlRORUVEUFJJTUFSWUxPQ0s7CgllbHNlCgkJY2FwZiA9IERTRERFU0NfRE9OVE5FRURTRUNPTkRBUllMT0NLOwoJaWYgKCEoVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBjYXBmKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9VbmxvY2soVGhpcy0+aHdidWYsIHAxLCB4MSwgcDIsIHgyKTsKCX0KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1Jlc3RvcmUoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRklYTUUoIiglcCk6c3R1YlxuIixUaGlzKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0RnJlcXVlbmN5KAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIGZyZXEKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwKVxuIixUaGlzLGZyZXEpOwoKCWlmIChmcmVxID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqZnJlcSA9IFRoaXMtPmZyZXE7CglUUkFDRSgiLT4gJWxkXG4iLCAqZnJlcSk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Jbml0aWFsaXplKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERJUkVDVFNPVU5EIGRzb3VuZCxMUERTQlVGRkVSREVTQyBkYnNkCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRklYTUUoIiglcCwlcCwlcCk6c3R1YlxuIixUaGlzLGRzb3VuZCxkYnNkKTsKCURQUklOVEYoIlJlLUluaXQhISFcbiIpOwoJcmV0dXJuIERTRVJSX0FMUkVBRFlJTklUSUFMSVpFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q2FwcygKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBEU0JDQVBTIGNhcHMKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CiAgCVRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsY2Fwcyk7CiAgCglpZiAoY2FwcyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogSSB0aGluayB3ZSBzaG91bGQgY2hlY2sgdGhpcyB2YWx1ZSwgbm90IHNldCBpdC4gU2VlICovCgkvKiBJbnNpZGUgRGlyZWN0WCwgcDIxNS4gVGhhdCBzaG91bGQgYXBwbHkgaGVyZSwgdG9vLiAqLwoJY2Fwcy0+ZHdTaXplID0gc2l6ZW9mKCpjYXBzKTsKCgljYXBzLT5kd0ZsYWdzID0gVGhpcy0+ZHNiZC5kd0ZsYWdzOwoJaWYgKFRoaXMtPmh3YnVmKSBjYXBzLT5kd0ZsYWdzIHw9IERTQkNBUFNfTE9DSEFSRFdBUkU7CgllbHNlIGNhcHMtPmR3RmxhZ3MgfD0gRFNCQ0FQU19MT0NTT0ZUV0FSRTsKCgljYXBzLT5kd0J1ZmZlckJ5dGVzID0gVGhpcy0+ZHNiZC5kd0J1ZmZlckJ5dGVzOwoKCS8qIFRoaXMgdmFsdWUgcmVwcmVzZW50cyB0aGUgc3BlZWQgb2YgdGhlICJ1bmxvY2siIGNvbW1hbmQuCgkgICBBcyB1bmxvY2sgaXMgcXVpdGUgZmFzdCAoaXQgZG9lcyBub3QgZG8gYW55dGhpbmcpLCBJIHB1dAoJICAgNDA5NiBrby9zID0gNCBNbyAvIHMgKi8KCS8qIEZJWE1FOiBod2J1ZiBzcGVlZCAqLwoJY2Fwcy0+ZHdVbmxvY2tUcmFuc2ZlclJhdGUgPSA0MDk2OwoJY2Fwcy0+ZHdQbGF5Q3B1T3ZlcmhlYWQgPSAwOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZE5vdGlmeSwgcmlpZCApICkgewoJCUlEaXJlY3RTb3VuZE5vdGlmeUltcGwJKmRzbjsKCgkJZHNuID0gKElEaXJlY3RTb3VuZE5vdGlmeUltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCpkc24pKTsKCQlkc24tPnJlZiA9IDE7CgkJZHNuLT5kc2IgPSBUaGlzOwoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJCUlDT01fVlRCTChkc24pID0gJmRzbnZ0OwoJCSpwcG9iaiA9IChMUFZPSUQpZHNuOwoJCXJldHVybiBTX09LOwoJfQoKI2lmIFVTRV9EU09VTkQzRAoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQzREJ1ZmZlciwgcmlpZCApICkgewogICAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsICAgICAgICAqZHMzZGI7CgoJCSpwcG9iaiA9IFRoaXMtPmRzM2RiOwoJCWlmICgqcHBvYmopIHsKCQkJSURpcmVjdFNvdW5kM0RCdWZmZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RCVUZGRVIpVGhpcy0+ZHMzZGIpOwoJCQlyZXR1cm4gU19PSzsKCQl9CgogICAgICAgICAgICAgICAgZHMzZGIgPSAoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKICAgICAgICAgICAgICAgICAgICAgICAgMCxzaXplb2YoKmRzM2RiKSk7CiAgICAgICAgICAgICAgICBkczNkYi0+cmVmID0gMTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kc2IgPSAoKmlwcGRzYik7CiAgICAgICAgICAgICAgICBJQ09NX1ZUQkwoZHMzZGIpID0gJmRzM2RidnQ7CgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmZHMzZGItPmxvY2spOwoKCQlkczNkYi0+ZHMzZGIgPSBUaGlzOwoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcyk7CgogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3U2l6ZSA9IHNpemVvZihEUzNEQlVGRkVSKTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52UG9zaXRpb24ueC54ID0gMC4wOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLnZQb3NpdGlvbi55LnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlBvc2l0aW9uLnoueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52VmVsb2NpdHkueC54ID0gMC4wOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLnZWZWxvY2l0eS55LnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlZlbG9jaXR5LnoueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd0luc2lkZUNvbmVBbmdsZSA9IERTM0RfREVGQVVMVENPTkVBTkdMRTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd091dHNpZGVDb25lQW5nbGUgPSBEUzNEX0RFRkFVTFRDT05FQU5HTEU7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi54LnggPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi55LnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi56LnogPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIubENvbmVPdXRzaWRlVm9sdW1lID0gRFMzRF9ERUZBVUxUQ09ORU9VVFNJREVWT0xVTUU7ICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5mbE1pbkRpc3RhbmNlID0gRFMzRF9ERUZBVUxUTUlORElTVEFOQ0U7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZmxNYXhEaXN0YW5jZSA9IERTM0RfREVGQVVMVE1BWERJU1RBTkNFOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX05PUk1BTDsKICAgICAgICAgICAgICAgIGRzM2RiLT5idWZsZW4gPSAoKCppcHBkc2IpLT5idWZsZW4gKiBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ24pIC8KICAgICAgICAgICAgICAgICAgICAgICAgKCppcHBkc2IpLT53ZngubkJsb2NrQWxpZ247CiAgICAgICAgICAgICAgICBkczNkYi0+YnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzM2RiLT5idWZsZW4pOwogICAgICAgICAgICAgICAgaWYgKGRzM2RiLT5idWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBkczNkYi0+YnVmbGVuID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX0RJU0FCTEU7CiAgICAgICAgICAgICAgICB9CgoJCXJldHVybiBTX09LOwoJfQojZW5kaWYKCiAgICAgICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQzRExpc3RlbmVyLCByaWlkICkgKSB7CgkJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqIGRzbDsKCgkJaWYgKFRoaXMtPmRzb3VuZC0+bGlzdGVuZXIpIHsKCQkJKnBwb2JqID0gVGhpcy0+ZHNvdW5kLT5saXN0ZW5lcjsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lcl9BZGRSZWYoKExQRElSRUNUU09VTkQzRExJU1RFTkVSKVRoaXMtPmRzb3VuZC0+bGlzdGVuZXIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRFNfT0s7CgkJfQoKCQlkc2wgPSAoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCpkc2wpKTsKCQlkc2wtPnJlZiA9IDE7CgkJSUNPTV9WVEJMKGRzbCkgPSAmZHMzZGx2dDsKCQkqcHBvYmogPSAoTFBWT0lEKWRzbDsKCiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLmR3U2l6ZSA9IHNpemVvZihEUzNETElTVEVORVIpOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52UG9zaXRpb24udTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlBvc2l0aW9uLnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZQb3NpdGlvbi51My56ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52VmVsb2NpdHkudTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlZlbG9jaXR5LnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZWZWxvY2l0eS51My56ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50RnJvbnQudTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudEZyb250LnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRGcm9udC51My56ID0gMS4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50VG9wLnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRUb3AudTIueSA9IDEuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudFRvcC51My56ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC5mbERpc3RhbmNlRmFjdG9yID0gRFMzRF9ERUZBVUxURElTVEFOQ0VGQUNUT1I7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLmZsUm9sbG9mZkZhY3RvciA9IERTM0RfREVGQVVMVFJPTExPRkZGQUNUT1I7CgoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJmRzbC0+bG9jayk7CgoJCWRzbC0+ZHNiID0gVGhpczsKCQlJRGlyZWN0U291bmRCdWZmZXJfQWRkUmVmKGlmYWNlKTsKCgkJVGhpcy0+ZHNvdW5kLT5saXN0ZW5lciA9IGRzbDsKCQlJRGlyZWN0U291bmQzRExpc3RlbmVyX0FkZFJlZigoTFBESVJFQ1RTT1VORDNETElTVEVORVIpZHNsKTsKCgkJcmV0dXJuIFNfT0s7Cgl9CgoJRklYTUUoICJVbmtub3duIEdVSUQgJXNcbiIsIGRlYnVnc3RyX2d1aWQoIHJpaWQgKSApOwoKCSpwcG9iaiA9IE5VTEw7CgoJcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZEJ1ZmZlcikgZHNidnQgPSAKewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfUmVsZWFzZSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q2FwcywKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRGb3JtYXQsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFZvbHVtZSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0UGFuLAogICAgICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0RnJlcXVlbmN5LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRTdGF0dXMsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0luaXRpYWxpemUsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0xvY2ssCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1BsYXksCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEN1cnJlbnRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Rm9ybWF0LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRWb2x1bWUsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldFBhbiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0RnJlcXVlbmN5LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TdG9wLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9VbmxvY2ssCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1Jlc3RvcmUKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJRGlyZWN0U291bmQKICovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9TZXRDb29wZXJhdGl2ZUxldmVsKAoJTFBESVJFQ1RTT1VORCBpZmFjZSxIV05EIGh3bmQsRFdPUkQgbGV2ZWwKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlMDhseCwlbGQpOnN0dWJcbiIsVGhpcywoRFdPUkQpaHduZCxsZXZlbCk7CgoJVGhpcy0+cHJpb2xldmVsID0gbGV2ZWw7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9DcmVhdGVTb3VuZEJ1ZmZlcigKCUxQRElSRUNUU09VTkQgaWZhY2UsTFBEU0JVRkZFUkRFU0MgZHNiZCxMUExQRElSRUNUU09VTkRCVUZGRVIgcHBkc2IsTFBVTktOT1dOIGxwdW5rCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqIGlwcGRzYj0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqKXBwZHNiOwoJTFBXQVZFRk9STUFURVgJd2ZleDsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CgoJVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsVGhpcyxkc2JkLGlwcGRzYixscHVuayk7CgkKCWlmICgoVGhpcyA9PSBOVUxMKSB8fCAoZHNiZCA9PSBOVUxMKSB8fCAoaXBwZHNiID09IE5VTEwpKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgkKCWlmIChUUkFDRV9PTihkc291bmQpKSB7CgkJVFJBQ0UoIihzdHJ1Y3RzaXplPSVsZClcbiIsZHNiZC0+ZHdTaXplKTsKCQlUUkFDRSgiKGZsYWdzPTB4JTA4bHg6XG4iLGRzYmQtPmR3RmxhZ3MpOwoJCV9kdW1wX0RTQkNBUFMoZHNiZC0+ZHdGbGFncyk7CgkJRFBSSU5URigiKVxuIik7CgkJVFJBQ0UoIihidWZmZXJieXRlcz0lbGQpXG4iLGRzYmQtPmR3QnVmZmVyQnl0ZXMpOwoJCVRSQUNFKCIobHB3ZnhGb3JtYXQ9JXApXG4iLGRzYmQtPmxwd2Z4Rm9ybWF0KTsKCX0KCgl3ZmV4ID0gZHNiZC0+bHB3ZnhGb3JtYXQ7CgoJaWYgKHdmZXgpCgkJVFJBQ0UoIihmb3JtYXR0YWc9MHglMDR4LGNoYW5zPSVkLHNhbXBsZXJhdGU9JWxkLCIKCQkgICAiYnl0ZXNwZXJzZWM9JWxkLGJsb2NrYWxpZ249JWQsYml0c3BlcnNhbXA9JWQsY2JTaXplPSVkKVxuIiwKCQkgICB3ZmV4LT53Rm9ybWF0VGFnLCB3ZmV4LT5uQ2hhbm5lbHMsIHdmZXgtPm5TYW1wbGVzUGVyU2VjLAoJCSAgIHdmZXgtPm5BdmdCeXRlc1BlclNlYywgd2ZleC0+bkJsb2NrQWxpZ24sIAoJCSAgIHdmZXgtPndCaXRzUGVyU2FtcGxlLCB3ZmV4LT5jYlNpemUpOwoKCWlmIChkc2JkLT5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CgkJaWYgKHByaW1hcnlidWYpIHsKCQkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZigoTFBESVJFQ1RTT1VOREJVRkZFUilwcmltYXJ5YnVmKTsKCQkJKmlwcGRzYiA9IHByaW1hcnlidWY7CgkJCXByaW1hcnlidWYtPmRzYmQuZHdGbGFncyA9IGRzYmQtPmR3RmxhZ3M7CgkJCXJldHVybiBEU19PSzsKCQl9IC8qIEVsc2UgY3JlYXRlIHByaW1hcnkgYnVmZmVyICovCgl9CgoJKmlwcGRzYiA9IChJRGlyZWN0U291bmRCdWZmZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihJRGlyZWN0U291bmRCdWZmZXJJbXBsKSk7CglpZiAoKmlwcGRzYiA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCUlDT01fVlRCTCgqaXBwZHNiKSA9ICZkc2J2dDsKCSgqaXBwZHNiKS0+cmVmID0gMTsKCSgqaXBwZHNiKS0+ZHNvdW5kID0gVGhpczsKCSgqaXBwZHNiKS0+cGFyZW50ID0gTlVMTDsKCSgqaXBwZHNiKS0+YnVmZmVyID0gTlVMTDsKCgltZW1jcHkoJigoKmlwcGRzYiktPmRzYmQpLGRzYmQsc2l6ZW9mKCpkc2JkKSk7CglpZiAoZHNiZC0+bHB3ZnhGb3JtYXQpCgkJbWVtY3B5KCYoKCppcHBkc2IpLT53ZngpLCBkc2JkLT5scHdmeEZvcm1hdCwgc2l6ZW9mKCgqaXBwZHNiKS0+d2Z4KSk7CgoJVFJBQ0UoIkNyZWF0ZWQgYnVmZmVyIGF0ICVwXG4iLCAqaXBwZHNiKTsKCglpZiAoZHNiZC0+ZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgewoJCSgqaXBwZHNiKS0+YnVmbGVuID0gZHNvdW5kLT53ZngubkF2Z0J5dGVzUGVyU2VjOwoJCSgqaXBwZHNiKS0+ZnJlcSA9IGRzb3VuZC0+d2Z4Lm5TYW1wbGVzUGVyU2VjOwoKCQkvKiBGSVhNRTogdmVyaWZ5IHRoYXQgaGFyZHdhcmUgY2FwYWJpbGl0aWVzIChEU0NBUFNfUFJJTUFSWSBmbGFncykgbWF0Y2ggKi8KCgkJaWYgKFRoaXMtPmRyaXZlcikgewoJCQllcnIgPSBJRHNEcml2ZXJfQ3JlYXRlU291bmRCdWZmZXIoVGhpcy0+ZHJpdmVyLHdmZXgsZHNiZC0+ZHdGbGFncywwLAoJCQkJCQkJICAmKCgqaXBwZHNiKS0+YnVmbGVuKSwmKCgqaXBwZHNiKS0+YnVmZmVyKSwKCQkJCQkJCSAgKExQVk9JRCopJigoKmlwcGRzYiktPmh3YnVmKSk7CgkJfQoJCWlmIChlcnIgPT0gRFNfT0spCgkJCWVyciA9IERTT1VORF9QcmltYXJ5T3BlbigqaXBwZHNiKTsKCX0gZWxzZSB7CgkJRFdPUkQgY2FwZiA9IDA7CgkJaW50IHVzZV9odzsKCgkJKCppcHBkc2IpLT5idWZsZW4gPSBkc2JkLT5kd0J1ZmZlckJ5dGVzOwoJCSgqaXBwZHNiKS0+ZnJlcSA9IGRzYmQtPmxwd2Z4Rm9ybWF0LT5uU2FtcGxlc1BlclNlYzsKCgkJLyogQ2hlY2sgbmVjZXNzYXJ5IGhhcmR3YXJlIG1peGluZyBjYXBhYmlsaXRpZXMgKi8KCQlpZiAod2ZleC0+bkNoYW5uZWxzPT0yKSBjYXBmIHw9IERTQ0FQU19TRUNPTkRBUllTVEVSRU87CgkJZWxzZSBjYXBmIHw9IERTQ0FQU19TRUNPTkRBUllNT05POwoJCWlmICh3ZmV4LT53Qml0c1BlclNhbXBsZT09MTYpIGNhcGYgfD0gRFNDQVBTX1NFQ09OREFSWTE2QklUOwoJCWVsc2UgY2FwZiB8PSBEU0NBUFNfU0VDT05EQVJZOEJJVDsKCQl1c2VfaHcgPSAoVGhpcy0+ZHJ2Y2Fwcy5kd0ZsYWdzICYgY2FwZikgPT0gY2FwZjsKCgkJLyogRklYTUU6IGNoZWNrIGhhcmR3YXJlIHNhbXBsZSByYXRlIG1peGluZyBjYXBhYmlsaXRpZXMgKi8KCQkvKiBGSVhNRTogY2hlY2sgYXBwIGhpbnRzIGZvciBzb2Z0d2FyZS9oYXJkd2FyZSBidWZmZXIgKFNUQVRJQywgTE9DSEFSRFdBUkUsIGV0YykgKi8KCQkvKiBGSVhNRTogY2hlY2sgd2hldGhlciBhbnkgaGFyZHdhcmUgYnVmZmVycyBhcmUgbGVmdCAqLwoJCS8qIEZJWE1FOiBoYW5kbGUgRFNESEVBUF9DUkVBVEVIRUFQIGZvciBoYXJkd2FyZSBidWZmZXJzICovCgoJCS8qIEFsbG9jYXRlIHN5c3RlbSBtZW1vcnkgaWYgYXBwbGljYWJsZSAqLwoJCWlmICgoVGhpcy0+ZHJ2ZGVzYy5kd0ZsYWdzICYgRFNEREVTQ19VU0VTWVNURU1NRU1PUlkpIHx8ICF1c2VfaHcpIHsKCQkJKCppcHBkc2IpLT5idWZmZXIgPSAoTFBCWVRFKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsKCppcHBkc2IpLT5idWZsZW4pOwoJCQlpZiAoKCppcHBkc2IpLT5idWZmZXIgPT0gTlVMTCkKCQkJCWVyciA9IERTRVJSX09VVE9GTUVNT1JZOwoJCX0KCgkJLyogQWxsb2NhdGUgdGhlIGhhcmR3YXJlIGJ1ZmZlciAqLwoJCWlmICh1c2VfaHcgJiYgKGVyciA9PSBEU19PSykpIHsKCQkJZXJyID0gSURzRHJpdmVyX0NyZWF0ZVNvdW5kQnVmZmVyKFRoaXMtPmRyaXZlcix3ZmV4LGRzYmQtPmR3RmxhZ3MsMCwKCQkJCQkJCSAgJigoKmlwcGRzYiktPmJ1ZmxlbiksJigoKmlwcGRzYiktPmJ1ZmZlciksCgkJCQkJCQkgIChMUFZPSUQqKSYoKCppcHBkc2IpLT5od2J1ZikpOwoJCX0KCX0KCglpZiAoZXJyICE9IERTX09LKSB7CgkJaWYgKCgqaXBwZHNiKS0+YnVmZmVyKQoJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKCppcHBkc2IpLT5idWZmZXIpOwoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCwoKmlwcGRzYikpOwoJCSppcHBkc2IgPSBOVUxMOwoJCXJldHVybiBlcnI7Cgl9CgkvKiBjYWxjdWxhdGUgZnJhZ21lbnQgc2l6ZSBhbmQgd3JpdGUgbGVhZCAqLwoJRFNPVU5EX1JlY2FsY0Zvcm1hdCgqaXBwZHNiKTsKCgkvKiBJdCdzIG5vdCBuZWNlc3NhcnkgdG8gaW5pdGlhbGl6ZSB2YWx1ZXMgdG8gemVybyBzaW5jZSAqLwoJLyogd2UgYWxsb2NhdGVkIHRoaXMgc3RydWN0dXJlIHdpdGggSEVBUF9aRVJPX01FTU9SWS4uLiAqLwoJKCppcHBkc2IpLT5wbGF5cG9zID0gMDsKCSgqaXBwZHNiKS0+bWl4cG9zID0gMDsKCSgqaXBwZHNiKS0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJRFNPVU5EX1JlY2FsY1ZvbFBhbigmKCgqaXBwZHNiKS0+dm9scGFuKSk7CgoJaWYgKCEoZHNiZC0+ZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikpIHsKCQkoKmlwcGRzYiktPmZyZXFBZGp1c3QgPSAoKCppcHBkc2IpLT5mcmVxIDw8IERTT1VORF9GUkVRU0hJRlQpIC8KCQkJcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjOwoJCSgqaXBwZHNiKS0+bkF2Z0J5dGVzUGVyU2VjID0gKCppcHBkc2IpLT5mcmVxICoKCQkJZHNiZC0+bHB3ZnhGb3JtYXQtPm5CbG9ja0FsaWduOwoJfQoKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogcmVnaXN0ZXIgYnVmZmVyICovCglpZiAoIShkc2JkLT5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSkgewoJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKipuZXdidWZmZXJzID0gKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKilIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+YnVmZmVycyxzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCopKihUaGlzLT5ucm9mYnVmZmVycysxKSk7CgkJaWYgKG5ld2J1ZmZlcnMpIHsKCQkJVGhpcy0+YnVmZmVycyA9IG5ld2J1ZmZlcnM7CgkJCVRoaXMtPmJ1ZmZlcnNbVGhpcy0+bnJvZmJ1ZmZlcnNdID0gKmlwcGRzYjsKCQkJVGhpcy0+bnJvZmJ1ZmZlcnMrKzsKCQkJVFJBQ0UoImJ1ZmZlciBjb3VudCBpcyBub3cgJWRcbiIsIFRoaXMtPm5yb2ZidWZmZXJzKTsKCQl9IGVsc2UgewoJCQlFUlIoIm91dCBvZiBtZW1vcnkgZm9yIGJ1ZmZlciBsaXN0ISBDdXJyZW50IGJ1ZmZlciBjb3VudCBpcyAlZFxuIiwgVGhpcy0+bnJvZmJ1ZmZlcnMpOwoJCQllcnIgPSBEU0VSUl9PVVRPRk1FTU9SWTsKCQl9Cgl9CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglJRGlyZWN0U291bmRfQWRkUmVmKGlmYWNlKTsKCglJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCYoKCppcHBkc2IpLT5sb2NrKSk7CgoJaWYgKGVyciAhPSBEU19PSykgewoJCS8qIG9vcHMuLi4gKi8KCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgqcHBkc2IpOwoJCSppcHBkc2IgPSBOVUxMOwoJCXJldHVybiBlcnI7Cgl9CgkKI2lmIFVTRV9EU09VTkQzRAoJaWYgKGRzYmQtPmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkgewoJCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbAkqZHMzZGI7CgoJCWRzM2RiID0gKElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCgkJCTAsc2l6ZW9mKCpkczNkYikpOwoJCUlDT01fVlRCTChkczNkYikgPSAmZHMzZGJ2dDsKCQlkczNkYi0+cmVmID0gMTsKCQkoKmlwcGRzYiktPmRzM2RiID0gZHMzZGI7CgoJCWRzM2RiLT5kc2IgPSAoKmlwcGRzYik7CgkJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9BZGRSZWYoKExQRElSRUNUU09VTkRCVUZGRVIpaXBwZHNiKTsKCgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmZHMzZGItPmxvY2spOwoKCQlkczNkYi0+ZHMzZGIuZHdTaXplID0gc2l6ZW9mKERTM0RCVUZGRVIpOwoJCWRzM2RiLT5kczNkYi52UG9zaXRpb24ueC54ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52UG9zaXRpb24ueS55ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52UG9zaXRpb24uei56ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52VmVsb2NpdHkueC54ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52VmVsb2NpdHkueS55ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52VmVsb2NpdHkuei56ID0gMC4wOwoJCWRzM2RiLT5kczNkYi5kd0luc2lkZUNvbmVBbmdsZSA9IERTM0RfREVGQVVMVENPTkVBTkdMRTsKCQlkczNkYi0+ZHMzZGIuZHdPdXRzaWRlQ29uZUFuZ2xlID0gRFMzRF9ERUZBVUxUQ09ORUFOR0xFOwoJCWRzM2RiLT5kczNkYi52Q29uZU9yaWVudGF0aW9uLngueCA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi55LnkgPSAwLjA7CgkJZHMzZGItPmRzM2RiLnZDb25lT3JpZW50YXRpb24uei56ID0gMC4wOwoJCWRzM2RiLT5kczNkYi5sQ29uZU91dHNpZGVWb2x1bWUgPSBEUzNEX0RFRkFVTFRDT05FT1VUU0lERVZPTFVNRTsKCQlkczNkYi0+ZHMzZGIuZmxNaW5EaXN0YW5jZSA9IERTM0RfREVGQVVMVE1JTkRJU1RBTkNFOwoJCWRzM2RiLT5kczNkYi5mbE1heERpc3RhbmNlID0gRFMzRF9ERUZBVUxUTUFYRElTVEFOQ0U7CgkJZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX05PUk1BTDsKCQlkczNkYi0+YnVmbGVuID0gKCgqaXBwZHNiKS0+YnVmbGVuICogcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduKSAvCgkJCSgqaXBwZHNiKS0+d2Z4Lm5CbG9ja0FsaWduOwoJCWRzM2RiLT5idWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHMzZGItPmJ1Zmxlbik7CgkJaWYgKGRzM2RiLT5idWZmZXIgPT0gTlVMTCkgewoJCQlkczNkYi0+YnVmbGVuID0gMDsKCQkJZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX0RJU0FCTEU7CgkJfQoJfQojZW5kaWYKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfRHVwbGljYXRlU291bmRCdWZmZXIoCglMUERJUkVDVFNPVU5EIGlmYWNlLExQRElSRUNUU09VTkRCVUZGRVIgcGRzYixMUExQRElSRUNUU09VTkRCVUZGRVIgcHBkc2IKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBpcGRzYj0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCopcGRzYjsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKiBpcHBkc2I9KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKilwcGRzYjsKCVRSQUNFKCIoJXAsJXAsJXApXG4iLFRoaXMsaXBkc2IsaXBwZHNiKTsKCglpZiAoaXBkc2ItPmh3YnVmKSB7CgkJRklYTUUoIm5lZWQgdG8gZHVwbGljYXRlIGhhcmR3YXJlIGJ1ZmZlclxuIik7Cgl9CgoJKmlwcGRzYiA9IChJRGlyZWN0U291bmRCdWZmZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihJRGlyZWN0U291bmRCdWZmZXJJbXBsKSk7CgoJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZihwZHNiKTsKCW1lbWNweSgqaXBwZHNiLCBpcGRzYiwgc2l6ZW9mKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwpKTsKCSgqaXBwZHNiKS0+cmVmID0gMTsKCSgqaXBwZHNiKS0+cGxheXBvcyA9IDA7CgkoKmlwcGRzYiktPm1peHBvcyA9IDA7CgkoKmlwcGRzYiktPmRzb3VuZCA9IFRoaXM7CgkoKmlwcGRzYiktPnBhcmVudCA9IGlwZHNiOwoJbWVtY3B5KCYoKCppcHBkc2IpLT53ZngpLCAmKGlwZHNiLT53ZngpLCBzaXplb2YoKCppcHBkc2IpLT53ZngpKTsKCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJigqaXBwZHNiKS0+bG9jayk7CgkvKiByZWdpc3RlciBidWZmZXIgKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJewoJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKipuZXdidWZmZXJzID0gKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKilIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+YnVmZmVycyxzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqKSooVGhpcy0+bnJvZmJ1ZmZlcnMrMSkpOwoJCWlmIChuZXdidWZmZXJzKSB7CgkJCVRoaXMtPmJ1ZmZlcnMgPSBuZXdidWZmZXJzOwoJCQlUaGlzLT5idWZmZXJzW1RoaXMtPm5yb2ZidWZmZXJzXSA9ICppcHBkc2I7CgkJCVRoaXMtPm5yb2ZidWZmZXJzKys7CgkJCVRSQUNFKCJidWZmZXIgY291bnQgaXMgbm93ICVkXG4iLCBUaGlzLT5ucm9mYnVmZmVycyk7CgkJfSBlbHNlIHsKCQkJRVJSKCJvdXQgb2YgbWVtb3J5IGZvciBidWZmZXIgbGlzdCEgQ3VycmVudCBidWZmZXIgY291bnQgaXMgJWRcbiIsIFRoaXMtPm5yb2ZidWZmZXJzKTsKCQkJLyogRklYTUU6IHJlbGVhc2UgYnVmZmVyICovCgkJfQoJfQoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CglJRGlyZWN0U291bmRfQWRkUmVmKGlmYWNlKTsKCXJldHVybiBEU19PSzsKfQoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0dldENhcHMoTFBESVJFQ1RTT1VORCBpZmFjZSxMUERTQ0FQUyBjYXBzKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwKVxuIixUaGlzLGNhcHMpOwoJVFJBQ0UoIihmbGFncz0weCUwOGx4KVxuIixjYXBzLT5kd0ZsYWdzKTsKCglpZiAoY2FwcyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogV2Ugc2hvdWxkIGNoZWNrIHRoaXMgdmFsdWUsIG5vdCBzZXQgaXQuIFNlZSBJbnNpZGUgRGlyZWN0WCwgcDIxNS4gKi8KCWNhcHMtPmR3U2l6ZSA9IHNpemVvZigqY2Fwcyk7CgoJY2Fwcy0+ZHdGbGFncyA9IFRoaXMtPmRydmNhcHMuZHdGbGFnczsKCgkvKiBGSVhNRTogY29weSBjYXBzIGZyb20gVGhpcy0+ZHJ2Y2FwcyAqLwoJY2Fwcy0+ZHdNaW5TZWNvbmRhcnlTYW1wbGVSYXRlCQk9IERTQkZSRVFVRU5DWV9NSU47CgljYXBzLT5kd01heFNlY29uZGFyeVNhbXBsZVJhdGUJCT0gRFNCRlJFUVVFTkNZX01BWDsKCgljYXBzLT5kd1ByaW1hcnlCdWZmZXJzCQkJPSAxOwoKCWNhcHMtPmR3TWF4SHdNaXhpbmdBbGxCdWZmZXJzCQk9IDA7CgljYXBzLT5kd01heEh3TWl4aW5nU3RhdGljQnVmZmVycwk9IDA7CgljYXBzLT5kd01heEh3TWl4aW5nU3RyZWFtaW5nQnVmZmVycwk9IDA7CgoJY2Fwcy0+ZHdGcmVlSHdNaXhpbmdBbGxCdWZmZXJzCQk9IDA7CgljYXBzLT5kd0ZyZWVId01peGluZ1N0YXRpY0J1ZmZlcnMJPSAwOwoJY2Fwcy0+ZHdGcmVlSHdNaXhpbmdTdHJlYW1pbmdCdWZmZXJzCT0gMDsKCgljYXBzLT5kd01heEh3M0RBbGxCdWZmZXJzCQk9IDA7CgljYXBzLT5kd01heEh3M0RTdGF0aWNCdWZmZXJzCQk9IDA7CgljYXBzLT5kd01heEh3M0RTdHJlYW1pbmdCdWZmZXJzCQk9IDA7CgoJY2Fwcy0+ZHdGcmVlSHczREFsbEJ1ZmZlcnMJCT0gMDsKCWNhcHMtPmR3RnJlZUh3M0RTdGF0aWNCdWZmZXJzCQk9IDA7CgljYXBzLT5kd0ZyZWVIdzNEU3RyZWFtaW5nQnVmZmVycwk9IDA7CgoJY2Fwcy0+ZHdUb3RhbEh3TWVtQnl0ZXMJCQk9IDA7CgoJY2Fwcy0+ZHdGcmVlSHdNZW1CeXRlcwkJCT0gMDsKCgljYXBzLT5kd01heENvbnRpZ0ZyZWVId01lbUJ5dGVzCQk9IDA7CgoJY2Fwcy0+ZHdVbmxvY2tUcmFuc2ZlclJhdGVId0J1ZmZlcnMJPSA0MDk2OwkvKiBCdXQgd2UgaGF2ZSBub25lLi4uICovCgoJY2Fwcy0+ZHdQbGF5Q3B1T3ZlcmhlYWRTd0J1ZmZlcnMJPSAxOwkvKiAxJSAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5EIGlmYWNlKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglyZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX1JlbGVhc2UoTFBESVJFQ1RTT1VORCBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCksIHJlZiB3YXMgJWxkXG4iLFRoaXMsVGhpcy0+cmVmKTsKCWlmICghLS0oVGhpcy0+cmVmKSkgewoJCVVJTlQgaTsKCgkJdGltZUtpbGxFdmVudChUaGlzLT50aW1lcklEKTsKCQl0aW1lRW5kUGVyaW9kKERTX1RJTUVfUkVTKTsKCgkJaWYgKHByaW1hcnlidWYpCgkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKXByaW1hcnlidWYpOwoKCQlpZiAoVGhpcy0+YnVmZmVycykgewoJCQlmb3IoIGk9MDtpPFRoaXMtPm5yb2ZidWZmZXJzO2krKykJCgkJCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5idWZmZXJzW2ldKTsKCQl9CgoJCWlmIChUaGlzLT5wcmltYXJ5KQoJCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5wcmltYXJ5KTsKCgkJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCZUaGlzLT5sb2NrKTsKCQlpZiAoVGhpcy0+ZHJpdmVyKSB7CgkJCUlEc0RyaXZlcl9DbG9zZShUaGlzLT5kcml2ZXIpOwoJCX0gZWxzZSB7CgkJCXVuc2lnbmVkIGM7CgkJCWZvciAoYz0wOyBjPERTX0hFTF9GUkFHUzsgYysrKQoJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPnB3YXZlW2NdKTsKCQl9CgkJaWYgKFRoaXMtPmRydmRlc2MuZHdGbGFncyAmIERTRERFU0NfRE9NTVNZU1RFTU9QRU4pIHsKCQkJd2F2ZU91dENsb3NlKFRoaXMtPmh3byk7CgkJfQoJCWlmIChUaGlzLT5kcml2ZXIpCgkJCUlEc0RyaXZlcl9SZWxlYXNlKFRoaXMtPmRyaXZlcik7CgoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCQlkc291bmQgPSBOVUxMOwoJCXJldHVybiAwOwoJfQoJcmV0dXJuIFRoaXMtPnJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfU2V0U3BlYWtlckNvbmZpZygKCUxQRElSRUNUU09VTkQgaWZhY2UsRFdPUkQgY29uZmlnCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJRklYTUUoIiglcCwweCUwOGx4KTpzdHViXG4iLFRoaXMsY29uZmlnKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5EIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CgoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQzRExpc3RlbmVyLCByaWlkICkgKSB7CgoJCWlmIChUaGlzLT5saXN0ZW5lcikgewoJCQkqcHBvYmogPSBUaGlzLT5saXN0ZW5lcjsKCQkJSURpcmVjdFNvdW5kM0RMaXN0ZW5lcl9BZGRSZWYoKExQRElSRUNUU09VTkQzRExJU1RFTkVSKVRoaXMtPmxpc3RlbmVyKTsKCQkJcmV0dXJuIERTX09LOwoJCX0KCgkJVGhpcy0+bGlzdGVuZXIgPSAoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqKUhlYXBBbGxvYygKCQkJR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCooVGhpcy0+bGlzdGVuZXIpKSk7CgkJVGhpcy0+bGlzdGVuZXItPnJlZiA9IDE7CgkJSUNPTV9WVEJMKFRoaXMtPmxpc3RlbmVyKSA9ICZkczNkbHZ0OwoJCSpwcG9iaiA9IChMUFZPSUQpVGhpcy0+bGlzdGVuZXI7CgkJSURpcmVjdFNvdW5kM0RMaXN0ZW5lcl9BZGRSZWYoKExQRElSRUNUU09VTkQzRExJU1RFTkVSKSpwcG9iaik7CQoKCQlUaGlzLT5saXN0ZW5lci0+ZHNiID0gTlVMTDsgCgoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC5kd1NpemUgPSBzaXplb2YoRFMzRExJU1RFTkVSKTsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlBvc2l0aW9uLnUxLnggPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZQb3NpdGlvbi51Mi55ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52UG9zaXRpb24udTMueiA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlZlbG9jaXR5LnUxLnggPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZWZWxvY2l0eS51Mi55ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52VmVsb2NpdHkudTMueiA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudEZyb250LnUxLnggPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRGcm9udC51Mi55ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50RnJvbnQudTMueiA9IDEuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudFRvcC51MS54ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50VG9wLnUyLnkgPSAxLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRUb3AudTMueiA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwuZmxEaXN0YW5jZUZhY3RvciA9IERTM0RfREVGQVVMVERJU1RBTkNFRkFDVE9SOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC5mbFJvbGxvZmZGYWN0b3IgPSBEUzNEX0RFRkFVTFRST0xMT0ZGRkFDVE9SOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC5mbERvcHBsZXJGYWN0b3IgPSBEUzNEX0RFRkFVTFRET1BQTEVSRkFDVE9SOwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZUaGlzLT5saXN0ZW5lci0+bG9jayk7CgoJCXJldHVybiBEU19PSzsKCX0KCglGSVhNRSgiKCVwLCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoJcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfQ29tcGFjdCgKCUxQRElSRUNUU09VTkQgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfR2V0U3BlYWtlckNvbmZpZygKCUxQRElSRUNUU09VTkQgaWZhY2UsCglMUERXT1JEIGxwZHdTcGVha2VyQ29uZmlnKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCAlcClcbiIsIFRoaXMsIGxwZHdTcGVha2VyQ29uZmlnKTsKCSpscGR3U3BlYWtlckNvbmZpZyA9IERTU1BFQUtFUl9TVEVSRU8gfCAoRFNTUEVBS0VSX0dFT01FVFJZX05BUlJPVyA8PCAxNik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0luaXRpYWxpemUoCglMUERJUkVDVFNPVU5EIGlmYWNlLAoJTFBDR1VJRCBscGNHdWlkKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCAlcClcbiIsIFRoaXMsIGxwY0d1aWQpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kKSBkc3Z0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglJRGlyZWN0U291bmRJbXBsX1F1ZXJ5SW50ZXJmYWNlLAoJSURpcmVjdFNvdW5kSW1wbF9BZGRSZWYsCglJRGlyZWN0U291bmRJbXBsX1JlbGVhc2UsCglJRGlyZWN0U291bmRJbXBsX0NyZWF0ZVNvdW5kQnVmZmVyLAoJSURpcmVjdFNvdW5kSW1wbF9HZXRDYXBzLAoJSURpcmVjdFNvdW5kSW1wbF9EdXBsaWNhdGVTb3VuZEJ1ZmZlciwKCUlEaXJlY3RTb3VuZEltcGxfU2V0Q29vcGVyYXRpdmVMZXZlbCwKCUlEaXJlY3RTb3VuZEltcGxfQ29tcGFjdCwKCUlEaXJlY3RTb3VuZEltcGxfR2V0U3BlYWtlckNvbmZpZywKCUlEaXJlY3RTb3VuZEltcGxfU2V0U3BlYWtlckNvbmZpZywKCUlEaXJlY3RTb3VuZEltcGxfSW5pdGlhbGl6ZQp9OwoKCnN0YXRpYyB2b2lkIERTT1VORF9DaGVja0V2ZW50KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgaW50IGxlbikKewoJaW50CQkJaTsKCURXT1JECQkJb2Zmc2V0OwoJTFBEU0JQT1NJVElPTk5PVElGWQlldmVudDsKCglpZiAoZHNiLT5ucm9mbm90aWZpZXMgPT0gMCkKCQlyZXR1cm47CgoJVFJBQ0UoIiglcCkgYnVmbGVuID0gJWxkLCBwbGF5cG9zID0gJWxkLCBsZW4gPSAlZFxuIiwKCQlkc2IsIGRzYi0+YnVmbGVuLCBkc2ItPnBsYXlwb3MsIGxlbik7Cglmb3IgKGkgPSAwOyBpIDwgZHNiLT5ucm9mbm90aWZpZXMgOyBpKyspIHsKCQlldmVudCA9IGRzYi0+bm90aWZpZXMgKyBpOwoJCW9mZnNldCA9IGV2ZW50LT5kd09mZnNldDsKCQlUUkFDRSgiY2hlY2tpbmcgJWQsIHBvc2l0aW9uICVsZCwgZXZlbnQgPSAlZFxuIiwKCQkJaSwgb2Zmc2V0LCBldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkvKiBEU0JQTl9PRkZTRVRTVE9QIGhhcyB0byBiZSB0aGUgbGFzdCBlbGVtZW50LiBTbyB0aGlzIGlzICovCgkJLyogT0suIFtJbnNpZGUgRGlyZWN0WCwgcDI3NF0gKi8KCQkvKiAgKi8KCQkvKiBUaGlzIGFsc28gbWVhbnMgd2UgY2FuJ3Qgc29ydCB0aGUgZW50cmllcyBieSBvZmZzZXQsICovCgkJLyogYmVjYXVzZSBEU0JQTl9PRkZTRVRTVE9QID09IC0xICovCgkJaWYgKG9mZnNldCA9PSBEU0JQTl9PRkZTRVRTVE9QKSB7CgkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlZCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCXJldHVybjsKCQkJfSBlbHNlCgkJCQlyZXR1cm47CgkJfQoJCWlmICgoZHNiLT5wbGF5cG9zICsgbGVuKSA+PSBkc2ItPmJ1ZmxlbikgewoJCQlpZiAoKG9mZnNldCA8ICgoZHNiLT5wbGF5cG9zICsgbGVuKSAlIGRzYi0+YnVmbGVuKSkgfHwKCQkJICAgIChvZmZzZXQgPj0gZHNiLT5wbGF5cG9zKSkgewoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlZCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKChvZmZzZXQgPj0gZHNiLT5wbGF5cG9zKSAmJiAob2Zmc2V0IDwgKGRzYi0+cGxheXBvcyArIGxlbikpKSB7CgkJCQlUUkFDRSgic2lnbmFsbGVkIGV2ZW50ICVkICglZClcbiIsIGV2ZW50LT5oRXZlbnROb3RpZnksIGkpOwoJCQkJU2V0RXZlbnQoZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJCX0KCQl9Cgl9Cn0KCi8qIFdBViBmb3JtYXQgaW5mbyBjYW4gYmUgZm91bmQgYXQ6ICovCi8qICovCi8qCWh0dHA6Ly93d3cuY3dpLm5sL2Z0cC9hdWRpby9BdWRpb0Zvcm1hdHMucGFydDIgKi8KLyoJZnRwOi8vZnRwLmN3aS5ubC9wdWIvYXVkaW8vUklGRi1mb3JtYXQgKi8KLyogKi8KLyogSW1wb3J0IHBvaW50cyB0byByZW1lbWJlcjogKi8KLyogKi8KLyoJOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCi8qCTE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgpzdGF0aWMgaW5saW5lIElOVDE2IGN2dFU4dG9TMTYoQllURSBieXRlKQp7CglJTlQxNglzID0gKGJ5dGUgLSAxMjgpIDw8IDg7CgoJcmV0dXJuIHM7Cn0KCnN0YXRpYyBpbmxpbmUgQllURSBjdnRTMTZ0b1U4KElOVDE2IHdvcmQpCnsKCUJZVEUJYiA9ICh3b3JkICsgMzI3NjgpID4+IDg7CgkKCXJldHVybiBiOwp9CgoKLyogV2Ugc2hvdWxkIGJlIGFibGUgdG8gb3B0aW1pemUgdGhlc2UgdHdvIGlubGluZSBmdW5jdGlvbnMgKi8KLyogc28gdGhhdCB3ZSBhcmVuJ3QgZG9pbmcgOC0+MTYtPjggY29udmVyc2lvbnMgd2hlbiBpdCBpcyAqLwovKiBub3QgbmVjZXNzYXJ5LiBCdXQgdGhpcyBpcyBzdGlsbCBhIFdJUC4gT3B0aW1pemUgbGF0ZXIuICovCnN0YXRpYyBpbmxpbmUgdm9pZCBnZXRfZmllbGRzKGNvbnN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgKmZsLCBJTlQgKmZyKQp7CglJTlQxNgkqYnVmcyA9IChJTlQxNiAqKSBidWY7CgoJLyogVFJBQ0UoIiglcCkiLCBidWYpOyAqLwoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMikgewoJCSpmbCA9IGN2dFU4dG9TMTYoKmJ1Zik7CgkJKmZyID0gY3Z0VTh0b1MxNigqKGJ1ZiArIDEpKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgJiYgZHNiLT53ZngubkNoYW5uZWxzID09IDIpIHsKCQkqZmwgPSAqYnVmczsKCQkqZnIgPSAqKGJ1ZnMgKyAxKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMSkgewoJCSpmbCA9IGN2dFU4dG9TMTYoKmJ1Zik7CgkJKmZyID0gKmZsOwoJCXJldHVybjsKCX0KCglpZiAoKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMSkgewoJCSpmbCA9ICpidWZzOwoJCSpmciA9ICpidWZzOwoJCXJldHVybjsKCX0KCglGSVhNRSgiZ2V0X2ZpZWxkcyBmb3VuZCBhbiB1bnN1cHBvcnRlZCBjb25maWd1cmF0aW9uXG4iKTsKCXJldHVybjsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9maWVsZHMoQllURSAqYnVmLCBJTlQgZmwsIElOVCBmcikKewoJSU5UMTYgKmJ1ZnMgPSAoSU5UMTYgKikgYnVmOwoKCWlmICgocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDgpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDIpKSB7CgkJKmJ1ZiA9IGN2dFMxNnRvVTgoZmwpOwoJCSooYnVmICsgMSkgPSBjdnRTMTZ0b1U4KGZyKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDIpKSB7CgkJKmJ1ZnMgPSBmbDsKCQkqKGJ1ZnMgKyAxKSA9IGZyOwoJCXJldHVybjsKCX0KCglpZiAoKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAxKSkgewoJCSpidWYgPSBjdnRTMTZ0b1U4KChmbCArIGZyKSA+PiAxKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDEpKSB7CgkJKmJ1ZnMgPSAoZmwgKyBmcikgPj4gMTsKCQlyZXR1cm47Cgl9CglGSVhNRSgic2V0X2ZpZWxkcyBmb3VuZCBhbiB1bnN1cHBvcnRlZCBjb25maWd1cmF0aW9uXG4iKTsKCXJldHVybjsKfQoKLyogTm93IHdpdGggUGVyZmVjdFBpdGNoICh0bSkgdGVjaG5vbG9neSAqLwpzdGF0aWMgSU5UIERTT1VORF9NaXhlck5vcm0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBzaXplLCBpcG9zLCBpbGVuLCBmaWVsZEwsIGZpZWxkUjsKCUJZVEUJKmlicCwgKm9icDsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoKCWlicCA9IGRzYi0+YnVmZmVyICsgZHNiLT5taXhwb3M7CglvYnAgPSBidWY7CgoJVFJBQ0UoIiglcCwgJXAsICVwKSwgbWl4cG9zPSVsZFxuIiwgZHNiLCBpYnAsIG9icCwgZHNiLT5taXhwb3MpOwoJLyogQ2hlY2sgZm9yIHRoZSBiZXN0IGNhc2UgKi8KCWlmICgoZHNiLT5mcmVxID09IHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYykgJiYKCSAgICAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlKSAmJgoJICAgIChkc2ItPndmeC5uQ2hhbm5lbHMgPT0gcHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscykpIHsKCSAgICAgICAgRFdPUkQgYnl0ZXNsZWZ0ID0gZHNiLT5idWZsZW4gLSBkc2ItPm1peHBvczsKCQlUUkFDRSgiKCVwKSBCZXN0IGNhc2VcbiIsIGRzYik7CgkgICAgCWlmIChsZW4gPD0gYnl0ZXNsZWZ0ICkKCQkJbWVtY3B5KG9icCwgaWJwLCBsZW4pOwoJCWVsc2UgeyAvKiB3cmFwICovCgkJCW1lbWNweShvYnAsIGlicCwgYnl0ZXNsZWZ0ICk7CgkJCW1lbWNweShvYnAgKyBieXRlc2xlZnQsIGRzYi0+YnVmZmVyLCBsZW4gLSBieXRlc2xlZnQpOwoJCX0KCQlyZXR1cm4gbGVuOwoJfQoJCgkvKiBDaGVjayBmb3Igc2FtZSBzYW1wbGUgcmF0ZSAqLwoJaWYgKGRzYi0+ZnJlcSA9PSBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWMpIHsKCQlUUkFDRSgiKCVwKSBTYW1lIHNhbXBsZSByYXRlICVsZCA9IHByaW1hcnkgJWxkXG4iLCBkc2IsCgkJCWRzYi0+ZnJlcSwgcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjKTsKCQlpbGVuID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IG9BZHZhbmNlKSB7CgkJCWdldF9maWVsZHMoZHNiLCBpYnAsICZmaWVsZEwsICZmaWVsZFIpOwoJCQlpYnAgKz0gaUFkdmFuY2U7CgkJCWlsZW4gKz0gaUFkdmFuY2U7CgkJCXNldF9maWVsZHMob2JwLCBmaWVsZEwsIGZpZWxkUik7CgkJCW9icCArPSBvQWR2YW5jZTsKCQkJaWYgKGlicCA+PSAoQllURSAqKShkc2ItPmJ1ZmZlciArIGRzYi0+YnVmbGVuKSkKCQkJCWlicCA9IGRzYi0+YnVmZmVyOwkvKiB3cmFwICovCgkJfQoJCXJldHVybiAoaWxlbik7CQoJfQoKCS8qIE1peCBpbiBkaWZmZXJlbnQgc2FtcGxlIHJhdGVzICovCgkvKiAqLwoJLyogTmV3IFBlcmZlY3RQaXRjaCh0bSkgVGVjaG5vbG9neSAoYykgMTk5OCBSb2IgUmlnZ3MgKi8KCS8qIFBhdGVudCBQZW5kaW5nIDotXSAqLwoKCVRSQUNFKCIoJXApIEFkanVzdGluZyBmcmVxdWVuY3k6ICVsZCAtPiAlbGRcbiIsCgkJZHNiLCBkc2ItPmZyZXEsIHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYyk7CgoJc2l6ZSA9IGxlbiAvIG9BZHZhbmNlOwoJaWxlbiA9ICgoc2l6ZSAqIGRzYi0+ZnJlcUFkanVzdCkgPj4gRFNPVU5EX0ZSRVFTSElGVCkgKiBpQWR2YW5jZTsKCWZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCgkJaXBvcyA9ICgoKGkgKiBkc2ItPmZyZXFBZGp1c3QpID4+IERTT1VORF9GUkVRU0hJRlQpICogaUFkdmFuY2UpICsgZHNiLT5taXhwb3M7CgoJCWlmIChpcG9zID49IGRzYi0+YnVmbGVuKQoJCQlpcG9zICU9IGRzYi0+YnVmbGVuOwkvKiB3cmFwICovCgoJCWdldF9maWVsZHMoZHNiLCAoZHNiLT5idWZmZXIgKyBpcG9zKSwgJmZpZWxkTCwgJmZpZWxkUik7CgkJc2V0X2ZpZWxkcyhvYnAsIGZpZWxkTCwgZmllbGRSKTsKCQlvYnAgKz0gb0FkdmFuY2U7Cgl9CglyZXR1cm4gaWxlbjsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peGVyVm9sKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgbGVuKQp7CglJTlQJaSwgaW5jID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID4+IDM7CglCWVRFCSpicGMgPSBidWY7CglJTlQxNgkqYnBzID0gKElOVDE2ICopIGJ1ZjsKCQoJVFJBQ0UoIiglcCkgbGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIGRzYiwKCQlkc2ItPnZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvciwgZHNiLT52b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKTsKCWlmICgoIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwgKGRzYi0+dm9scGFuLmxQYW4gPT0gMCkpICYmCgkgICAgKCEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8IChkc2ItPnZvbHBhbi5sVm9sdW1lID09IDApKSAmJgoJICAgICEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkpCgkJcmV0dXJuOwkJLyogTm90aGluZyB0byBkbyAqLwoKCS8qIElmIHdlIGVuZCB1cCB3aXRoIHNvbWUgYm96byBjb2RlciB1c2luZyBwYW5uaW5nIG9yIDNEIHNvdW5kICovCgkvKiB3aXRoIGEgbW9ubyBwcmltYXJ5IGJ1ZmZlciwgaXQgY291bGQgc291bmQgdmVyeSB3ZWlyZCB1c2luZyAqLwoJLyogdGhpcyBtZXRob2QuIE9oIHdlbGwsIHRvdWdoIHBhdG9vdGllcy4gKi8KCglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IGluYykgewoJCUlOVAl2YWw7CgoJCXN3aXRjaCAoaW5jKSB7CgoJCWNhc2UgMToKCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkLCBidXQgd2UgbmVlZCB0byBvcGVyYXRlICovCgkJCS8qIG9uIHNpZ25lZCBkYXRhIGZvciB0aGlzIHRvIHdvcmsgcHJvcGVybHkgKi8KCQkJdmFsID0gKmJwYyAtIDEyODsKCQkJdmFsID0gKCh2YWwgKiAoaSAmIGluYyA/IGRzYi0+dm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3RvciA6IGRzYi0+dm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSkgPj4gMTYpOwoJCQkqYnBjID0gdmFsICsgMTI4OwoJCQlicGMrKzsKCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAtLSBtdWNoIGJldHRlciAqLwoJCQl2YWwgPSAqYnBzOwoJCQl2YWwgPSAoKHZhbCAqICgoaSAmIGluYykgPyBkc2ItPnZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgOiBkc2ItPnZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvcikpID4+IDE2KTsKCQkJKmJwcyA9IHZhbDsKCQkJYnBzKys7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCS8qIFZlcnkgdWdseSEgKi8KCQkJRklYTUUoIk1peGVyVm9sIGhhZCBhIG5hc3R5IGVycm9yXG4iKTsKCQl9Cgl9CQkKfQoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgdm9pZCBEU09VTkRfTWl4ZXIzRChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIEJZVEUgKmJ1ZiwgSU5UIGxlbikKewoJQllURQkqaWJwLCAqb2JwOwoJRFdPUkQJYnVmbGVuLCBtaXhwb3M7CgoJYnVmbGVuID0gZHNiLT5kczNkYi0+YnVmbGVuOwoJbWl4cG9zID0gKGRzYi0+bWl4cG9zICogcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduKSAvIGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJaWJwID0gZHNiLT5kczNkYi0+YnVmZmVyICsgbWl4cG9zOwoJb2JwID0gYnVmOwoKCWlmIChtaXhwb3MgPiBidWZsZW4pIHsKCQlGSVhNRSgiTWFqb3IgYnJlYWthZ2UiKTsKCQlyZXR1cm47Cgl9CgoJaWYgKGxlbiA8PSAobWl4cG9zICsgYnVmbGVuKSkKCQltZW1jcHkob2JwLCBpYnAsIGxlbik7CgllbHNlIHsgLyogd3JhcCAqLwoJCW1lbWNweShvYnAsIGlicCwgYnVmbGVuIC0gbWl4cG9zKTsKCQltZW1jcHkob2JwICsgKGJ1ZmxlbiAtIG1peHBvcyksCgkJICAgIGRzYi0+YnVmZmVyLAoJCSAgICBsZW4gLSAoYnVmbGVuIC0gbWl4cG9zKSk7Cgl9CglyZXR1cm47Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZCAqdG1wX2J1ZmZlcjsKc3RhdGljIHNpemVfdCB0bXBfYnVmZmVyX2xlbiA9IDA7CgpzdGF0aWMgdm9pZCAqRFNPVU5EX3RtcGJ1ZmZlcihzaXplX3QgbGVuKQp7CiAgaWYgKGxlbj50bXBfYnVmZmVyX2xlbikgewogICAgdm9pZCAqbmV3X2J1ZmZlciA9IHJlYWxsb2ModG1wX2J1ZmZlciwgbGVuKTsKICAgIGlmIChuZXdfYnVmZmVyKSB7CiAgICAgIHRtcF9idWZmZXIgPSBuZXdfYnVmZmVyOwogICAgICB0bXBfYnVmZmVyX2xlbiA9IGxlbjsKICAgIH0KICAgIHJldHVybiBuZXdfYnVmZmVyOwogIH0KICByZXR1cm4gdG1wX2J1ZmZlcjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhJbkJ1ZmZlcihJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBmcmFnbGVuKQp7CglJTlQJaSwgbGVuLCBpbGVuLCB0ZW1wLCBmaWVsZDsKCUlOVAlhZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID4+IDM7CglCWVRFCSpidWYsICppYnVmLCAqb2J1ZjsKCUlOVDE2CSppYnVmcywgKm9idWZzOwoKCWxlbiA9IGZyYWdsZW47CglpZiAoIShkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykpIHsKCQl0ZW1wID0gTXVsRGl2KHByaW1hcnlidWYtPndmeC5uQXZnQnl0ZXNQZXJTZWMsIGRzYi0+YnVmbGVuLAoJCQlkc2ItPm5BdmdCeXRlc1BlclNlYykgLQoJCSAgICAgICBNdWxEaXYocHJpbWFyeWJ1Zi0+d2Z4Lm5BdmdCeXRlc1BlclNlYywgZHNiLT5taXhwb3MsCgkJCWRzYi0+bkF2Z0J5dGVzUGVyU2VjKTsKCQlsZW4gPSAobGVuID4gdGVtcCkgPyB0ZW1wIDogbGVuOwoJfQoJbGVuICY9IH4zOwkJCQkvKiA0IGJ5dGUgYWxpZ25tZW50ICovCgoJaWYgKGxlbiA9PSAwKSB7CgkJLyogVGhpcyBzaG91bGQgb25seSBoYXBwZW4gaWYgd2UgYXJlbid0IGxvb3BpbmcgYW5kIHRlbXAgPCA0ICovCgoJCS8qIFdlIHNraXAgdGhlIHJlbWFpbmRlciwgc28gY2hlY2sgZm9yIHBvc3NpYmxlIGV2ZW50cyAqLwoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgZHNiLT5idWZsZW4gLSBkc2ItPm1peHBvcyk7CgkJLyogU3RvcCAqLwoJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCWRzYi0+cGxheXBvcyA9IDA7CgkJZHNiLT5taXhwb3MgPSAwOwoJCWRzYi0+bGVhZGluID0gRkFMU0U7CgkJLyogQ2hlY2sgZm9yIERTQlBOX09GRlNFVFNUT1AgKi8KCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIDApOwoJCXJldHVybiAwOwoJfQoKCS8qIEJlZW4gc2VlaW5nIHNlZ2ZhdWx0cyBpbiBtYWxsb2MoKSBmb3Igc29tZSByZWFzb24uLi4gKi8KCVRSQUNFKCJhbGxvY2F0aW5nIGJ1ZmZlciAoc2l6ZSA9ICVkKVxuIiwgbGVuKTsKCWlmICgoYnVmID0gaWJ1ZiA9IChCWVRFICopIERTT1VORF90bXBidWZmZXIobGVuKSkgPT0gTlVMTCkKCQlyZXR1cm4gMDsKCglUUkFDRSgiTWl4SW5CdWZmZXIgKCVwKSBsZW4gPSAlZCwgZGVzdCA9ICVsZFxuIiwgZHNiLCBsZW4sIHdyaXRlcG9zKTsKCglpbGVuID0gRFNPVU5EX01peGVyTm9ybShkc2IsIGlidWYsIGxlbik7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkpCgkJRFNPVU5EX01peGVyVm9sKGRzYiwgaWJ1ZiwgbGVuKTsKCglvYnVmID0gcHJpbWFyeWJ1Zi0+YnVmZmVyICsgd3JpdGVwb3M7Cglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IGFkdmFuY2UpIHsKCQlvYnVmcyA9IChJTlQxNiAqKSBvYnVmOwoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQlmaWVsZCA9ICgqaWJ1ZiAtIDEyOCk7CgkJCWZpZWxkICs9ICgqb2J1ZiAtIDEyOCk7CgkJCWZpZWxkID0gZmllbGQgPiAxMjcgPyAxMjcgOiBmaWVsZDsKCQkJZmllbGQgPSBmaWVsZCA8IC0xMjggPyAtMTI4IDogZmllbGQ7CgkJCSpvYnVmID0gZmllbGQgKyAxMjg7CgkJfSBlbHNlIHsKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJZmllbGQgPSAqaWJ1ZnM7CgkJCWZpZWxkICs9ICpvYnVmczsKCQkJZmllbGQgPSBmaWVsZCA+IDMyNzY3ID8gMzI3NjcgOiBmaWVsZDsKCQkJZmllbGQgPSBmaWVsZCA8IC0zMjc2OCA/IC0zMjc2OCA6IGZpZWxkOwoJCQkqb2J1ZnMgPSBmaWVsZDsKCQl9CgkJaWJ1ZiArPSBhZHZhbmNlOwoJCW9idWYgKz0gYWR2YW5jZTsKCQlpZiAob2J1ZiA+PSAoQllURSAqKShwcmltYXJ5YnVmLT5idWZmZXIgKyBwcmltYXJ5YnVmLT5idWZsZW4pKQoJCQlvYnVmID0gcHJpbWFyeWJ1Zi0+YnVmZmVyOwoJfQoJLyogZnJlZShidWYpOyAqLwoKCWlmIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBPU0lUSU9OTk9USUZZKQoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgaWxlbik7CgoJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zID4gZHNiLT5taXhwb3MpICYmIChkc2ItPnN0YXJ0cG9zIDw9IGRzYi0+bWl4cG9zICsgaWxlbikpIHsKCQkvKiBIQUNLLi4uIGxlYWRpbiBzaG91bGQgYmUgcmVzZXQgd2hlbiB0aGUgUExBWSBwb3NpdGlvbiByZWFjaGVzIHRoZSBzdGFydHBvcywKCQkgKiBub3QgdGhlIE1JWCBwb3NpdGlvbi4uLiBidXQgaWYgdGhlIHNvdW5kIGJ1ZmZlciBpcyBiaWdnZXIgdGhhbiBvdXIgcHJlYnVmZmVyaW5nCgkJICogKHdoaWNoIG11c3QgYmUgdGhlIGNhc2UgZm9yIHRoZSBzdHJlYW1pbmcgYnVmZmVycyB0aGF0IG5lZWQgdGhpcyBoYWNrIGFueXdheSkKCQkgKiBwbHVzIERTX0hFTF9NQVJHSU4gb3IgZXF1aXZhbGVudCwgdGhlbiB0aGlzIG91Z2h0IHRvIHdvcmsgYW55d2F5LiAqLwoJCWRzYi0+bGVhZGluID0gRkFMU0U7Cgl9CgoJZHNiLT5taXhwb3MgKz0gaWxlbjsKCQoJaWYgKGRzYi0+bWl4cG9zID49IGRzYi0+YnVmbGVuKSB7CgkJaWYgKCEoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpKSB7CgkJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQlkc2ItPnBsYXlwb3MgPSAwOwoJCQlkc2ItPm1peHBvcyA9IDA7CgkJCWRzYi0+bGVhZGluID0gRkFMU0U7CgkJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgMCk7CQkvKiBGb3IgRFNCUE5fT0ZGU0VUU1RPUCAqLwoJCX0gZWxzZSB7CgkJCS8qIHdyYXAgKi8KCQkJd2hpbGUgKGRzYi0+bWl4cG9zID49IGRzYi0+YnVmbGVuKQoJCQkJZHNiLT5taXhwb3MgLT0gZHNiLT5idWZsZW47CgkJCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA8PSBkc2ItPm1peHBvcykpCgkJCQlkc2ItPmxlYWRpbiA9IEZBTFNFOyAvKiBIQUNLOiBzZWUgYWJvdmUgKi8KCQl9Cgl9CgoJcmV0dXJuIGxlbjsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBEU09VTkRfTWl4UHJpbWFyeShEV09SRCB3cml0ZXBvcywgRFdPUkQgZnJhZ2xlbiwgQk9PTCBzdGFydGluZykKewoJSU5UCQkJaSwgbGVuLCBtYXhsZW4gPSAwOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbAkqZHNiOwoKCVRSQUNFKCIoJWxkLCVsZCwlZClcbiIsIHdyaXRlcG9zLCBmcmFnbGVuLCBzdGFydGluZyk7Cglmb3IgKGkgPSBkc291bmQtPm5yb2ZidWZmZXJzIC0gMTsgaSA+PSAwOyBpLS0pIHsKCQlkc2IgPSBkc291bmQtPmJ1ZmZlcnNbaV07CgoJCWlmICghZHNiIHx8ICEoSUNPTV9WVEJMKGRzYikpKQoJCQljb250aW51ZTsKIAkJaWYgKGRzYi0+YnVmbGVuICYmIGRzYi0+c3RhdGUgJiYgIShzdGFydGluZyAmJiAoZHNiLT5zdGF0ZSAhPSBTVEFURV9TVEFSVElORykpKSB7CgkJCVRSQUNFKCJDaGVja2luZyAlcFxuIiwgZHNiKTsKCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJCS8qIEZJWE1FOiBwZXJoYXBzIGF0dGVtcHQgdG8gcmVtb3ZlIHRoZSBidWZmZXIgZnJvbSB0aGUgcHJlYnVmZmVyICovCgkJCQlkc2ItPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJfSBlbHNlIHsKCQkJCWxlbiA9IERTT1VORF9NaXhJbkJ1ZmZlcihkc2IsIHdyaXRlcG9zLCBmcmFnbGVuKTsKCQkJCW1heGxlbiA9IGxlbiA+IG1heGxlbiA/IGxlbiA6IG1heGxlbjsKCQkJfQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCX0KCX0KCQoJcmV0dXJuIG1heGxlbjsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIERTT1VORF9NYXJrUGxheWluZyh2b2lkKQp7CglJTlQJCQlpOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbAkqZHNiOwoKCWZvciAoaSA9IGRzb3VuZC0+bnJvZmJ1ZmZlcnMgLSAxOyBpID49IDA7IGktLSkgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyc1tpXTsKCgkJaWYgKCFkc2IgfHwgIShJQ09NX1ZUQkwoZHNiKSkpCgkJCWNvbnRpbnVlOwogCQlpZiAoZHNiLT5idWZsZW4gJiYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpKQogCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7Cgl9Cn0KCnN0YXRpYyB2b2lkIENBTExCQUNLIERTT1VORF90aW1lcihVSU5UIHRpbWVySUQsIFVJTlQgbXNnLCBEV09SRCBkd1VzZXIsIERXT1JEIGR3MSwgRFdPUkQgZHcyKQp7CglEV09SRCBsZW47CglpbnQgbmZpbGxlcjsKCUJPT0wgZm9yY2VkOwoKCWlmICghZHNvdW5kIHx8ICFwcmltYXJ5YnVmKSB7CgkJRVJSKCJkc291bmQgZGllZCB3aXRob3V0IGtpbGxpbmcgdXM/XG4iKTsKCQl0aW1lS2lsbEV2ZW50KHRpbWVySUQpOwoJCXRpbWVFbmRQZXJpb2QoRFNfVElNRV9SRVMpOwoJCXJldHVybjsKCX0KCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bG9jaykpOwoKCWlmICghcHJpbWFyeWJ1ZiB8fCAhcHJpbWFyeWJ1Zi0+cmVmKSB7CgkJLyogc2VlbXMgdGhlIHByaW1hcnkgYnVmZmVyIGlzIGN1cnJlbnRseSBiZWluZyByZWxlYXNlZCAqLwoJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJcmV0dXJuOwoJfQoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDggPyAxMjggOiAwOwoKCS8qIHdoZXRoZXIgdGhlIHByaW1hcnkgaXMgZm9yY2VkIHRvIHBsYXkgZXZlbiB3aXRob3V0IHNlY29uZGFyeSBidWZmZXJzICovCglmb3JjZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoKCWlmIChwcmltYXJ5YnVmLT5od2J1ZikgewoJCWlmIChkc291bmQtPnByaW9sZXZlbCAhPSBEU1NDTF9XUklURVBSSU1BUlkpIHsKCQkJQk9PTCBwYXVzZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoJCQlEV09SRCBwbGF5cG9zLCB3cml0ZXBvcywgaW5xLCBtYXhxLCBtaXhxLCBmcmFnOwoJCQlJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24ocHJpbWFyeWJ1Zi0+aHdidWYsICZwbGF5cG9zLCAmd3JpdGVwb3MpOwoJCQkvKiBXZWxsLCB3ZSAqY291bGQqIGRvIEp1c3QtSW4tVGltZSBtaXhpbmcgdXNpbmcgdGhlIHdyaXRlcG9zLAoJCQkgKiBidXQgdGhhdCdzIGEgbGl0dGxlIGJpdCBhbWJpdGlvdXMgYW5kIHVubmVjZXNzYXJ5Li4uICovCgkJCS8qIHJhdGhlciBhZGQgb3VyIHNhZmV0eSBtYXJnaW4gdG8gdGhlIHdyaXRlcG9zLCBpZiB3ZSdyZSBwbGF5aW5nICovCgkJCWlmICghcGF1c2VkKSB7CgkJCQl3cml0ZXBvcyArPSBwcmltYXJ5YnVmLT53cml0ZWxlYWQ7CgkJCQl3aGlsZSAod3JpdGVwb3MgPj0gcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQkJCXdyaXRlcG9zIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJfSBlbHNlIHdyaXRlcG9zID0gcGxheXBvczsKCQkJVFJBQ0UoInByaW1hcnkgcGxheXBvcz0lbGQsIHdyaXRlcG9zPSVsZCwgY2xycG9zPSVsZCwgbWl4cG9zPSVsZFxuIiwKCQkJICAgICAgcGxheXBvcyx3cml0ZXBvcyxwcmltYXJ5YnVmLT5wbGF5cG9zLHByaW1hcnlidWYtPm1peHBvcyk7CgkJCS8qIHdpcGUgb3V0IGp1c3QtcGxheWVkIHNvdW5kIGRhdGEgKi8KCQkJaWYgKHBsYXlwb3MgPCBwcmltYXJ5YnVmLT5wbGF5cG9zKSB7CgkJCQltZW1zZXQocHJpbWFyeWJ1Zi0+YnVmZmVyICsgcHJpbWFyeWJ1Zi0+cGxheXBvcywgbmZpbGxlciwgcHJpbWFyeWJ1Zi0+YnVmbGVuIC0gcHJpbWFyeWJ1Zi0+cGxheXBvcyk7CgkJCQltZW1zZXQocHJpbWFyeWJ1Zi0+YnVmZmVyLCBuZmlsbGVyLCBwbGF5cG9zKTsKCQkJfSBlbHNlIHsKCQkJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIgKyBwcmltYXJ5YnVmLT5wbGF5cG9zLCBuZmlsbGVyLCBwbGF5cG9zIC0gcHJpbWFyeWJ1Zi0+cGxheXBvcyk7CgkJCX0KCQkJcHJpbWFyeWJ1Zi0+cGxheXBvcyA9IHBsYXlwb3M7CgoJCQkvKiBjaGVjayBob3cgbXVjaCBwcmVidWZmZXJpbmcgaXMgbGVmdCAqLwoJCQlpbnEgPSBwcmltYXJ5YnVmLT5taXhwb3M7CgkJCWlmIChpbnEgPCB3cml0ZXBvcykKCQkJCWlucSArPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCWlucSAtPSB3cml0ZXBvczsKCgkJCS8qIGZpbmQgdGhlIG1heGltdW0gd2UgY2FuIHByZWJ1ZmZlciAqLwoJCQlpZiAoIXBhdXNlZCkgewoJCQkJbWF4cSA9IHBsYXlwb3M7CgkJCQlpZiAobWF4cSA8IHdyaXRlcG9zKQoJCQkJCW1heHEgKz0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJCQkJbWF4cSAtPSB3cml0ZXBvczsKCQkJfSBlbHNlIG1heHEgPSBwcmltYXJ5YnVmLT5idWZsZW47CgoJCQkvKiBjbGlwIG1heHEgdG8gRFNfSEFMX1FVRVVFICovCgkJCWZyYWcgPSBEU19IQUxfUVVFVUUgKiBkc291bmQtPmZyYWdsZW47CgkJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCgkJCS8qIGNoZWNrIGZvciBjb25zaXN0ZW5jeSAqLwoJCQlpZiAoaW5xID4gbWF4cSkgewoJCQkJLyogdGhlIHBsYXliYWNrIHBvc2l0aW9uIG11c3QgaGF2ZSBwYXNzZWQgb3VyIGxhc3QKCQkJCSAqIG1peGVkIHBvc2l0aW9uLCBpLmUuIGl0J3MgYW4gdW5kZXJydW4sIG9yIHdlIGhhdmUKCQkJCSAqIG5vdGhpbmcgbW9yZSB0byBwbGF5ICovCgkJCSAgICAgICAgaW5xID0gMDsKCQkJCS8qIHN0b3AgdGhlIHBsYXliYWNrIG5vdywgdG8gYWxsb3cgYnVmZmVycyB0byByZWZpbGwgKi8KCQkJCUlEc0RyaXZlckJ1ZmZlcl9TdG9wKHByaW1hcnlidWYtPmh3YnVmKTsKCQkJCWlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB7CgkJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJCX0KCQkJCWVsc2UgaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJLyogaG93IGNhbiB3ZSBoYXZlIGFuIHVuZGVycnVuIGlmIHdlIGFyZW4ndCBwbGF5aW5nPyAqLwoJCQkJCUVSUigidW5leHBlY3RlZCBwcmltYXJ5IHN0YXRlICglbGQpXG4iLCBwcmltYXJ5YnVmLT5zdGF0ZSk7CgkJCQl9CgkJCQkvKiB0aGUgU3RvcCBpcyBzdXBwb3NlZCB0byByZXNldCBwbGF5IHBvc2l0aW9uIHRvIGJlZ2lubmluZyBvZiBidWZmZXIgKi8KCQkJCS8qIHVuZm9ydHVuYXRlbHksIE9TUyBpcyBub3QgYWJsZSB0byBkbyBzbywgc28gZ2V0IGN1cnJlbnQgcG9pbnRlciAqLwoJCQkJSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKHByaW1hcnlidWYtPmh3YnVmLCAmcGxheXBvcywgTlVMTCk7CgkJCQl3cml0ZXBvcyA9IHBsYXlwb3M7CgkJCQlwcmltYXJ5YnVmLT5wbGF5cG9zID0gcGxheXBvczsKCQkJCXByaW1hcnlidWYtPm1peHBvcyA9IHBsYXlwb3M7CgkJCQlpbnEgPSAwOwoJCQkJbWF4cSA9IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgkJCQltZW1zZXQocHJpbWFyeWJ1Zi0+YnVmZmVyLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZsZW4pOwoJCQkJcGF1c2VkID0gVFJVRTsKCQkJfQoKCQkJLyogc2VlIGlmIHNvbWUgbmV3IGJ1ZmZlcnMgaGF2ZSBiZWVuIHN0YXJ0ZWQgdGhhdCB3ZSB3YW50IHRvIG1lcmdlIGludG8gb3VyIHByZWJ1ZmZlcjsKCQkJICogdGhpcyBzaG91bGQgbWluaW1pemUgbGF0ZW5jeSBldmVuIHdoZW4gd2UgaGF2ZSBhIGxhcmdlIHByZWJ1ZmZlciAqLwoJCQlpZiAoIXBhdXNlZCkgewoJCQkJaWYgKHByaW1hcnlidWYtPm1peHBvcyA8IHdyaXRlcG9zKSB7CgkJCQkJLyogbWl4IHRvIGVuZCBvZiBidWZmZXIgKi8KCQkJCQlsZW4gPSBEU09VTkRfTWl4UHJpbWFyeSh3cml0ZXBvcywgcHJpbWFyeWJ1Zi0+YnVmbGVuIC0gd3JpdGVwb3MsIFRSVUUpOwoJCQkJCWlmICgobGVuICsgd3JpdGVwb3MpIDwgcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQkJCQlnb3RvIGFkZG1peF9jb21wbGV0ZTsKCQkJCQkvKiBtaXggZnJvbSBiZWdpbm5pbmcgb2YgYnVmZmVyICovCgkJCQkJaWYgKHByaW1hcnlidWYtPm1peHBvcykKCQkJCQkJbGVuID0gRFNPVU5EX01peFByaW1hcnkoMCwgcHJpbWFyeWJ1Zi0+bWl4cG9zLCBUUlVFKTsKCQkJCX0gZWxzZSB7CgkJCQkJLyogbWl4IG1pZGRsZSBvZiBidWZmZXIgKi8KCQkJCQlsZW4gPSBEU09VTkRfTWl4UHJpbWFyeSh3cml0ZXBvcywgcHJpbWFyeWJ1Zi0+bWl4cG9zIC0gd3JpdGVwb3MsIFRSVUUpOwoJCQkJfQoJCQl9CgkJYWRkbWl4X2NvbXBsZXRlOgoJCQlEU09VTkRfTWFya1BsYXlpbmcoKTsKCgkJCW1peHEgPSBtYXhxIC0gaW5xOwoJCQlUUkFDRSgicXVldWVkICVsZCwgbWF4ICVsZCwgbWl4aW5nICVsZCwgcGF1c2VkICVkXG4iLCBpbnEsIG1heHEsIG1peHEsIHBhdXNlZCk7CgkJCS8qIGl0J3MgdG9vIGluZWZmaWNpZW50IHRvIG1peCBsZXNzIHRoYW4gYSBmcmFnbWVudCBhdCBhIHRpbWUgKi8KCQkJaWYgKG1peHEgPj0gZHNvdW5kLT5mcmFnbGVuKSB7CgojZGVmaW5lIEZSQUdfTUlYRVIgXAoJaWYgKGZyYWcgPiBtaXhxKSBmcmFnID0gbWl4cTsgXAoJbGVuID0gRFNPVU5EX01peFByaW1hcnkocHJpbWFyeWJ1Zi0+bWl4cG9zLCBmcmFnLCBGQUxTRSk7IFwKICAgICAgICBpZiAoZm9yY2VkKSBsZW4gPSBmcmFnOyBcCglwcmltYXJ5YnVmLT5taXhwb3MgKz0gbGVuOyBcCgltaXhxIC09IGxlbjsgaW5xICs9IGxlbgoKCQkJCWlmICgocGxheXBvcyA8IHdyaXRlcG9zKSB8fCAocGF1c2VkICYmIChwbGF5cG9zID09IHdyaXRlcG9zKSkpIHsKCQkJCQlpZiAocHJpbWFyeWJ1Zi0+bWl4cG9zKSB7CgkJCQkJCS8qIG1peCB0byBlbmQgb2YgYnVmZmVyICovCgkJCQkJCWZyYWcgPSBwcmltYXJ5YnVmLT5idWZsZW4gLSBwcmltYXJ5YnVmLT5taXhwb3M7CgkJCQkJCUZSQUdfTUlYRVI7CgkJCQkJCWlmIChwcmltYXJ5YnVmLT5taXhwb3MgPCBwcmltYXJ5YnVmLT5idWZsZW4pCgkJCQkJCQlnb3RvIG1peF9jb21wbGV0ZTsKCQkJCQkJcHJpbWFyeWJ1Zi0+bWl4cG9zID0gMDsKCQkJCQl9CgkJCQkJaWYgKG1peHEgPj0gZHNvdW5kLT5mcmFnbGVuKSB7CgkJCQkJCS8qIG1peCBmcm9tIGJlZ2lubmluZyBvZiBidWZmZXIgKi8KCQkJCQkJZnJhZyA9IHBsYXlwb3M7CgkJCQkJCWlmICgoIWZyYWcpICYmIHBhdXNlZCkgZnJhZyA9IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJCQkJRlJBR19NSVhFUjsKCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmIChwbGF5cG9zID4gd3JpdGVwb3MpIHsKCQkJCQkvKiBtaXggbWlkZGxlIG9mIGJ1ZmZlciAqLwoJCQkJCWZyYWcgPSBwbGF5cG9zIC0gcHJpbWFyeWJ1Zi0+bWl4cG9zOwoJCQkJCUZSQUdfTUlYRVI7CgkJCQl9CgkJCQllbHNlIHsKCQkJCQkvKiB0aGlzIHNob3VsZCBwcmVmZXJhYmx5IG5vdCBoYXBwZW4uLi4gKi8KCQkJCQlFUlIoIm1peGVyIG1hbGZ1bmN0aW9uIChhbWJpZ3VvdXMgd3JpdGVwb3MpIVxuIik7CgkJCQl9CiN1bmRlZiBGUkFHX01JWEVSCgkJCX0KCQltaXhfY29tcGxldGU6CgkJCWlmIChpbnEpIHsKCQkJCS8qIGJ1ZmZlcnMgaGF2ZSBiZWVuIGZpbGxlZCwgcmVzdGFydCBwbGF5YmFjayAqLwoJCQkJaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB7CgkJCQkJSURzRHJpdmVyQnVmZmVyX1BsYXkocHJpbWFyeWJ1Zi0+aHdidWYsIDAsIDAsIERTQlBMQVlfTE9PUElORyk7CgkJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQkJfQoJCQkJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCQkJCS8qIHRoZSBwcmltYXJ5YnVmIGlzIHN1cHBvc2VkIHRvIHBsYXkgaWYgdGhlcmUncyBzb21ldGhpbmcgdG8gcGxheQoJCQkJCSAqIGV2ZW4gaWYgaXQgaXMgcmVwb3J0ZWQgYXMgc3RvcHBlZCwgc28gZG9uJ3QgbGV0IHRoaXMgY29uZnVzZSB5b3UgKi8KCQkJCQlJRHNEcml2ZXJCdWZmZXJfUGxheShwcmltYXJ5YnVmLT5od2J1ZiwgMCwgMCwgRFNCUExBWV9MT09QSU5HKTsKCQkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJCQkJfQoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJCX0gZWxzZSB7CgkJCS8qIGluIHRoZSBEU1NDTF9XUklURVBSSU1BUlkgbW9kZSwgdGhlIGFwcCBpcyB0b3RhbGx5IGluIGNoYXJnZS4uLiAqLwoJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJCUlEc0RyaXZlckJ1ZmZlcl9QbGF5KHByaW1hcnlidWYtPmh3YnVmLCAwLCAwLCBEU0JQTEFZX0xPT1BJTkcpOwoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQl9IAoJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJSURzRHJpdmVyQnVmZmVyX1N0b3AocHJpbWFyeWJ1Zi0+aHdidWYpOwoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJfQoJfSBlbHNlIHsKCQkvKiB1c2luZyB3YXZlT3V0IHN0dWZmICovCgkJLyogaWYgbm8gYnVmZmVycyBhcmUgcGxheWluZywgd2Ugc2hvdWxkIGJlIGluIHBhdXNlIG1vZGUgbm93ICovCgkJRFdPUkQgd3JpdGVwb3M7CgkJLyogY2xlYW4gb3V0IGNvbXBsZXRlZCBmcmFnbWVudHMgKi8KCQl3aGlsZSAoZHNvdW5kLT5wd3F1ZXVlICYmIChkc291bmQtPnB3YXZlW2Rzb3VuZC0+cHdwbGF5XS0+ZHdGbGFncyAmIFdIRFJfRE9ORSkpIHsKCQkJaWYgKGRzb3VuZC0+cHJpb2xldmVsICE9IERTU0NMX1dSSVRFUFJJTUFSWSkgewoJCQkJRFdPUkQgcG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CgkJCQlUUkFDRSgiZG9uZSBwbGF5aW5nIHByaW1hcnkgcG9zPSVsZFxuIixwb3MpOwoJCQkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciArIHBvcywgbmZpbGxlciwgZHNvdW5kLT5mcmFnbGVuKTsKCQkJfQoJCQlkc291bmQtPnB3cGxheSsrOwoJCQlpZiAoZHNvdW5kLT5wd3BsYXkgPj0gRFNfSEVMX0ZSQUdTKSBkc291bmQtPnB3cGxheSA9IDA7CgkJCWRzb3VuZC0+cHdxdWV1ZS0tOwoJCX0KCQlwcmltYXJ5YnVmLT5wbGF5cG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CgkJVFJBQ0UoInByaW1hcnkgcGxheXBvcz0lbGQsIG1peHBvcz0lbGRcbiIscHJpbWFyeWJ1Zi0+cGxheXBvcyxwcmltYXJ5YnVmLT5taXhwb3MpOwoJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJCWlmICghZHNvdW5kLT5wd3F1ZXVlKSB7CgkJCS8qIHRoaXMgaXMgZWl0aGVyIGFuIHVuZGVycnVuIG9yIHdlIGhhdmUgbm90aGluZyBtb3JlIHRvIHBsYXkuLi4KCQkJICogc2luY2UgcGxheWJhY2sgaGFzIGFscmVhZHkgc3RvcHBlZCBub3csIHdlIGNhbiBlbnRlciBwYXVzZSBtb2RlLAoJCQkgKiBpbiBvcmRlciB0byBhbGxvdyBidWZmZXJzIHRvIHJlZmlsbCAqLwoJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgewoJCQkJd2F2ZU91dFBhdXNlKGRzb3VuZC0+aHdvKTsKCQkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJCX0KCQkJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJCXdhdmVPdXRQYXVzZShkc291bmQtPmh3byk7CgkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQl9CgoJCS8qIGZpbmQgbmV4dCB3cml0ZSBwb3NpdGlvbiwgcGx1cyBzb21lIGV4dHJhIG1hcmdpbiAqLwoJCXdyaXRlcG9zID0gcHJpbWFyeWJ1Zi0+cGxheXBvcyArIERTX0hFTF9NQVJHSU4gKiBkc291bmQtPmZyYWdsZW47CgkJd2hpbGUgKHdyaXRlcG9zID49IHByaW1hcnlidWYtPmJ1Zmxlbikgd3JpdGVwb3MgLT0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoKCQkvKiBzZWUgaWYgc29tZSBuZXcgYnVmZmVycyBoYXZlIGJlZW4gc3RhcnRlZCB0aGF0IHdlIHdhbnQgdG8gbWVyZ2UgaW50byBvdXIgcHJlYnVmZmVyOwoJCSAqIHRoaXMgc2hvdWxkIG1pbmltaXplIGxhdGVuY3kgZXZlbiB3aGVuIHdlIGhhdmUgYSBsYXJnZSBwcmVidWZmZXIgKi8KCQlpZiAoZHNvdW5kLT5wcmlvbGV2ZWwgIT0gRFNTQ0xfV1JJVEVQUklNQVJZKSB7CgkJCWlmICgocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgfHwgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSkgewoJCQkJd2hpbGUgKHdyaXRlcG9zICE9IHByaW1hcnlidWYtPm1peHBvcykgewoJCQkJCWxlbiA9IERTT1VORF9NaXhQcmltYXJ5KHdyaXRlcG9zLCBkc291bmQtPmZyYWdsZW4sIFRSVUUpOwoJCQkJCWlmICghbGVuKSBicmVhazsKCQkJCQl3cml0ZXBvcyArPSBkc291bmQtPmZyYWdsZW47CgkJCQkJaWYgKHdyaXRlcG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKCQkJCQkJd3JpdGVwb3MgLT0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJCQkJfQoJCQl9CgkJCURTT1VORF9NYXJrUGxheWluZygpOwoJCX0KCgkJLyogd2Ugd2FudCBhdCBsZWFzdCBEU19IRUxfUVVFVUUgZnJhZ21lbnRzIGluIHRoZSBwcmVidWZmZXIgb3V0cXVldWU7CgkJICogbWl4IGEgYnVuY2ggb2YgZnJhZ21lbnRzIG5vdyBhcyBuZWNlc3NhcnkgKi8KCQl3aGlsZSAoZHNvdW5kLT5wd3F1ZXVlIDwgRFNfSEVMX1FVRVVFKSB7CgkJCWlmIChkc291bmQtPnByaW9sZXZlbCAhPSBEU1NDTF9XUklURVBSSU1BUlkpIHsKCQkJCWxlbiA9IERTT1VORF9NaXhQcmltYXJ5KHByaW1hcnlidWYtPm1peHBvcywgZHNvdW5kLT5mcmFnbGVuLCBGQUxTRSk7CgkJCX0gZWxzZSBsZW49MDsKCQkJaWYgKGZvcmNlZCkgbGVuID0gZHNvdW5kLT5mcmFnbGVuOwoJCQkvKiBpZiB3ZSBoYXZlIG5vdGhpbmcgdG8gcGxheSwgZG9uJ3QgYm90aGVyIHRvICovCgkJCWlmICghbGVuKSBicmVhazsKCQkJaWYgKGxlbiA8IGRzb3VuZC0+ZnJhZ2xlbikgewoJCQkJVFJBQ0UoImxlbj0lbGQgaXMgbGVzcyB0aGFuIGZyYWdsZW49JWxkXG4iLGxlbixkc291bmQtPmZyYWdsZW4pOwoJCQl9CgkJCS8qIG9rLCB3ZSBoYXZlIHNvbWV0aGluZyB0byBwbGF5ICovCgkJCS8qIGFkdmFuY2UgbWl4IHBvc2l0aW9ucyAqLwoJCQlwcmltYXJ5YnVmLT5taXhwb3MgKz0gZHNvdW5kLT5mcmFnbGVuOwoJCQlpZiAocHJpbWFyeWJ1Zi0+bWl4cG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKCQkJCXByaW1hcnlidWYtPm1peHBvcyAtPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCS8qIG91dHB1dCBpdCAqLwoJCQl3YXZlT3V0V3JpdGUoZHNvdW5kLT5od28sIGRzb3VuZC0+cHdhdmVbZHNvdW5kLT5wd3dyaXRlXSwgc2l6ZW9mKFdBVkVIRFIpKTsKCQkJZHNvdW5kLT5wd3dyaXRlKys7CgkJCWlmIChkc291bmQtPnB3d3JpdGUgPj0gRFNfSEVMX0ZSQUdTKSBkc291bmQtPnB3d3JpdGUgPSAwOwoJCQlkc291bmQtPnB3cXVldWUrKzsKCQl9CgkJaWYgKGRzb3VuZC0+cHdxdWV1ZSkgewoJCQkvKiBidWZmZXJzIGhhdmUgYmVlbiBmaWxsZWQsIHJlc3RhcnQgcGxheWJhY2sgKi8KCQkJaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB7CgkJCQl3YXZlT3V0UmVzdGFydChkc291bmQtPmh3byk7CgkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7CgkJCX0KCQkJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCQkJLyogdGhlIHByaW1hcnlidWYgaXMgc3VwcG9zZWQgdG8gcGxheSBpZiB0aGVyZSdzIHNvbWV0aGluZyB0byBwbGF5CgkJCQkgKiBldmVuIGlmIGl0IGlzIHJlcG9ydGVkIGFzIHN0b3BwZWQsIHNvIGRvbid0IGxldCB0aGlzIGNvbmZ1c2UgeW91ICovCgkJCQl3YXZlT3V0UmVzdGFydChkc291bmQtPmh3byk7CgkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJCQl9CgkJfQoJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJfQoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPmxvY2spKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURpcmVjdFNvdW5kQ3JlYXRlCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENyZWF0ZShSRUZHVUlEIGxwR1VJRCxMUERJUkVDVFNPVU5EICpwcERTLElVbmtub3duICpwVW5rT3V0ZXIgKQp7CglJRGlyZWN0U291bmRJbXBsKiogaXBwRFM9KElEaXJlY3RTb3VuZEltcGwqKilwcERTOwoJUElEU0RSSVZFUiBkcnYgPSBOVUxMOwoJV0FWRU9VVENBUFNBIHdjYXBzOwoJdW5zaWduZWQgd29kLCB3b2RuOwoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCglpZiAobHBHVUlEKQoJCVRSQUNFKCIoJXAsJXAsJXApXG4iLGxwR1VJRCxpcHBEUyxwVW5rT3V0ZXIpOwoJZWxzZQoJCVRSQUNFKCJEaXJlY3RTb3VuZENyZWF0ZSAoJXApXG4iLCBpcHBEUyk7CgoJaWYgKGlwcERTID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCglpZiAocHJpbWFyeWJ1ZikgewoJCUlEaXJlY3RTb3VuZF9BZGRSZWYoKExQRElSRUNUU09VTkQpZHNvdW5kKTsKCQkqaXBwRFMgPSBkc291bmQ7CgkJcmV0dXJuIERTX09LOwoJfQoKCS8qIEVudW1lcmF0ZSBXSU5NTSBhdWRpbyBkZXZpY2VzIGFuZCBmaW5kIHRoZSBvbmUgd2Ugd2FudCAqLwoJd29kbiA9IHdhdmVPdXRHZXROdW1EZXZzKCk7CglpZiAoIXdvZG4pIHJldHVybiBEU0VSUl9OT0RSSVZFUjsKCgkvKiBGSVhNRTogSG93IGRvIHdlIGZpbmQgdGhlIEdVSUQgb2YgYW4gYXVkaW8gZGV2aWNlPyAqLwoJLyogV2VsbCwganVzdCB1c2UgdGhlIGZpcnN0IGF2YWlsYWJsZSBkZXZpY2UgZm9yIG5vdy4uLiAqLwoJd29kID0gMDsKCS8qIEdldCBvdXRwdXQgZGV2aWNlIGNhcHMgKi8KCXdhdmVPdXRHZXREZXZDYXBzQSh3b2QsICZ3Y2Fwcywgc2l6ZW9mKHdjYXBzKSk7CgkvKiAweDgxMCBpcyBhICJXaW5lIGV4dGVuc2lvbiIgdG8gZ2V0IHRoZSBEU291bmQgaW50ZXJmYWNlICovCgl3YXZlT3V0TWVzc2FnZSh3b2QsIDB4ODEwLCAoRFdPUkQpJmRydiwgMCk7CgoJLyogQWxsb2NhdGUgbWVtb3J5ICovCgkqaXBwRFMgPSAoSURpcmVjdFNvdW5kSW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxzaXplb2YoSURpcmVjdFNvdW5kSW1wbCkpOwoJaWYgKCppcHBEUyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCglJQ09NX1ZUQkwoKmlwcERTKQk9ICZkc3Z0OwoJKCppcHBEUyktPnJlZgkJPSAxOwoKCSgqaXBwRFMpLT5kcml2ZXIJPSBkcnY7CgkoKmlwcERTKS0+ZnJhZ2xlbgk9IDA7CgkoKmlwcERTKS0+cHJpb2xldmVsCT0gRFNTQ0xfTk9STUFMOyAKCSgqaXBwRFMpLT5ucm9mYnVmZmVycwk9IDA7CgkoKmlwcERTKS0+YnVmZmVycwk9IE5VTEw7CgkoKmlwcERTKS0+cHJpbWFyeQk9IE5VTEw7IAoJKCppcHBEUyktPmxpc3RlbmVyCT0gTlVMTDsgCgoJLyogR2V0IGRyaXZlciBkZXNjcmlwdGlvbiAqLwoJaWYgKGRydikgewoJCUlEc0RyaXZlcl9HZXREcml2ZXJEZXNjKGRydiwmKCgqaXBwRFMpLT5kcnZkZXNjKSk7Cgl9IGVsc2UgewoJCS8qIGlmIG5vIERpcmVjdFNvdW5kIGludGVyZmFjZSBhdmFpbGFibGUsIHVzZSBXSU5NTSBBUEkgaW5zdGVhZCAqLwoJCSgqaXBwRFMpLT5kcnZkZXNjLmR3RmxhZ3MgPSBEU0RERVNDX0RPTU1TWVNURU1PUEVOIHwgRFNEREVTQ19ET01NU1lTVEVNU0VURk9STUFUOwoJCSgqaXBwRFMpLT5kcnZkZXNjLmRuRGV2Tm9kZSA9IHdvZDsgLyogRklYTUU/ICovCgl9CgoJLyogU2V0IGRlZmF1bHQgd2F2ZSBmb3JtYXQgKG1heSBuZWVkIGl0IGZvciB3YXZlT3V0T3BlbikgKi8KCSgqaXBwRFMpLT53Zngud0Zvcm1hdFRhZwk9IFdBVkVfRk9STUFUX1BDTTsKCSgqaXBwRFMpLT53ZngubkNoYW5uZWxzCQk9IDI7CgkoKmlwcERTKS0+d2Z4Lm5TYW1wbGVzUGVyU2VjCT0gMjIwNTA7CgkoKmlwcERTKS0+d2Z4Lm5BdmdCeXRlc1BlclNlYwk9IDQ0MTAwOwoJKCppcHBEUyktPndmeC5uQmxvY2tBbGlnbgk9IDI7CgkoKmlwcERTKS0+d2Z4LndCaXRzUGVyU2FtcGxlCT0gODsKCgkvKiBJZiB0aGUgZHJpdmVyIHJlcXVlc3RzIGJlaW5nIG9wZW5lZCB0aHJvdWdoIE1NU1lTVEVNCgkgKiAod2hpY2ggaXMgcmVjb21tZW5kZWQgYnkgdGhlIERESyksIGl0IGlzIHN1cHBvc2VkIHRvIGhhcHBlbgoJICogYmVmb3JlIHRoZSBEaXJlY3RTb3VuZCBpbnRlcmZhY2UgaXMgb3BlbmVkICovCglpZiAoKCppcHBEUyktPmRydmRlc2MuZHdGbGFncyAmIERTRERFU0NfRE9NTVNZU1RFTU9QRU4pIHsKCQkvKiBGSVhNRTogaXMgdGhpcyByaWdodD8gKi8KCQllcnIgPSBtbUVycih3YXZlT3V0T3BlbigmKCgqaXBwRFMpLT5od28pLCAoKmlwcERTKS0+ZHJ2ZGVzYy5kbkRldk5vZGUsICYoKCppcHBEUyktPndmeCksCgkJCQkJMCwgMCwgQ0FMTEJBQ0tfTlVMTCB8IFdBVkVfRElSRUNUU09VTkQpKTsKCX0KCglpZiAoZHJ2ICYmIChlcnIgPT0gRFNfT0spKQoJCWVyciA9IElEc0RyaXZlcl9PcGVuKGRydik7CgoJLyogRklYTUU6IGRvIHdlIHdhbnQgdG8gaGFuZGxlIGEgdGVtcG9yYXJpbHkgYnVzeSBkZXZpY2U/ICovCglpZiAoZXJyICE9IERTX09LKSB7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCppcHBEUyk7CgkJKmlwcERTID0gTlVMTDsKCQlyZXR1cm4gZXJyOwoJfQoKCS8qIHRoZSBkcml2ZXIgaXMgbm93IG9wZW4sIHNvIGl0J3Mgbm93IGFsbG93ZWQgdG8gY2FsbCBHZXRDYXBzICovCglpZiAoZHJ2KSB7CgkJSURzRHJpdmVyX0dldENhcHMoZHJ2LCYoKCppcHBEUyktPmRydmNhcHMpKTsKCX0gZWxzZSB7CgkJdW5zaWduZWQgYzsKCgkJLyogRklYTUU6IGxvb2sgYXQgd2NhcHMgKi8KCQkoKmlwcERTKS0+ZHJ2Y2Fwcy5kd0ZsYWdzID0KCQkJRFNDQVBTX1BSSU1BUlkxNkJJVCB8IERTQ0FQU19QUklNQVJZU1RFUkVPOwoJCWlmIChEU19FTVVMRFJJVkVSKQoJCSAgICAoKmlwcERTKS0+ZHJ2Y2Fwcy5kd0ZsYWdzIHw9IERTQ0FQU19FTVVMRFJJVkVSOwoKCQkvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIEhFTCBidWZmZXIgaGVhZGVycyAqLwoJCWZvciAoYz0wOyBjPERTX0hFTF9GUkFHUzsgYysrKSB7CgkJCSgqaXBwRFMpLT5wd2F2ZVtjXSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKFdBVkVIRFIpKTsKCQkJaWYgKCEoKmlwcERTKS0+cHdhdmVbY10pIHsKCQkJCS8qIEFyZ2gsIG91dCBvZiBtZW1vcnkgKi8KCQkJCXdoaWxlIChjLS0pIHsKCQkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKCppcHBEUyktPnB3YXZlW2NdKTsKCQkJCQl3YXZlT3V0Q2xvc2UoKCppcHBEUyktPmh3byk7CgkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCppcHBEUyk7CgkJCQkJKmlwcERTID0gTlVMTDsKCQkJCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmKCgqaXBwRFMpLT5sb2NrKSk7CgoJaWYgKCFkc291bmQpIHsKCQlkc291bmQgPSAoKmlwcERTKTsKCQlpZiAocHJpbWFyeWJ1ZiA9PSBOVUxMKSB7CgkJCURTQlVGRkVSREVTQwlkc2JkOwoJCQlIUkVTVUxUCQlocjsKCgkJCWRzYmQuZHdTaXplID0gc2l6ZW9mKERTQlVGRkVSREVTQyk7CgkJCWRzYmQuZHdGbGFncyA9IERTQkNBUFNfUFJJTUFSWUJVRkZFUiB8IERTQkNBUFNfR0VUQ1VSUkVOVFBPU0lUSU9OMjsKCQkJZHNiZC5kd0J1ZmZlckJ5dGVzID0gMDsKCQkJZHNiZC5scHdmeEZvcm1hdCA9ICYoZHNvdW5kLT53ZngpOwoJCQlociA9IElEaXJlY3RTb3VuZF9DcmVhdGVTb3VuZEJ1ZmZlcigqcHBEUywgJmRzYmQsIChMUERJUkVDVFNPVU5EQlVGRkVSKikmcHJpbWFyeWJ1ZiwgTlVMTCk7CgkJCWlmIChociAhPSBEU19PSykKCQkJCXJldHVybiBocjsKCgkJCS8qIGRzb3VuZC0+cHJpbWFyeSBpcyBOVUxMIC0gZG9uJ3QgbmVlZCB0byBSZWxlYXNlICovCgkJCWRzb3VuZC0+cHJpbWFyeSA9IHByaW1hcnlidWY7CgkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoKExQRElSRUNUU09VTkRCVUZGRVIpcHJpbWFyeWJ1Zik7CgkJfQoJCXRpbWVCZWdpblBlcmlvZChEU19USU1FX1JFUyk7CgkJZHNvdW5kLT50aW1lcklEID0gdGltZVNldEV2ZW50KERTX1RJTUVfREVMLCBEU19USU1FX1JFUywgRFNPVU5EX3RpbWVyLAoJCQkJCSAgICAgICAoRFdPUkQpZHNvdW5kLCBUSU1FX1BFUklPRElDIHwgVElNRV9DQUxMQkFDS19GVU5DVElPTik7Cgl9CglyZXR1cm4gRFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRDYXB0dXJlQ3JlYXRlIFtEU09VTkQuNl0KICoKICogQ3JlYXRlIGFuZCBpbml0aWFsaXplIGEgRGlyZWN0U291bmRDYXB0dXJlIGludGVyZmFjZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERTX09LCiAqICAgIEZhaWx1cmU6IERTRVJSX05PQUdHUkVHQVRJT04sIERTRVJSX0FMTE9DQVRFRCwgRFNFUlJfSU5WQUxJRFBBUkFNLAogKiAgICAgICAgICAgICBEU0VSUl9PVVRPRk1FTU9SWQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRDYXB0dXJlQ3JlYXRlKAoJTFBDR1VJRCBscGNHVUlELAoJTFBESVJFQ1RTT1VORENBUFRVUkUqIGxwbHBEU0MsCglMUFVOS05PV04gcFVua091dGVyICkKewoJVFJBQ0UoIiglcywlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQobHBjR1VJRCksIGxwbHBEU0MsIHBVbmtPdXRlcik7CgoJaWYoIHBVbmtPdXRlciApIHsKCQlyZXR1cm4gRFNFUlJfTk9BR0dSRUdBVElPTjsKCX0KCgkvKiBEZWZhdWx0IGRldmljZT8gKi8KCWlmICggIWxwY0dVSUQgKSB7CgkJcmV0dXJuIERTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmUoIChMUFZPSUQqKWxwbHBEU0MgKTsKCX0KCglGSVhNRSggIlVua25vd24gR1VJRCAlc1xuIiwgZGVidWdzdHJfZ3VpZChscGNHVUlEKSApOwoJKmxwbHBEU0MgPSBOVUxMOwoKCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZENhcHR1cmVFbnVtZXJhdGVBIFtEU09VTkQuN10KICoKICogRW51bWVyYXRlIGFsbCBEaXJlY3RTb3VuZCBkcml2ZXJzIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfSU5WQUxJRFBBUkFNCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENhcHR1cmVFbnVtZXJhdGVBKAogICAgICAgIExQRFNFTlVNQ0FMTEJBQ0tBIGxwRFNFbnVtQ2FsbGJhY2ssCiAgICAgICAgTFBWT0lEIGxwQ29udGV4dCkKewoJVFJBQ0UoIiglcCwlcClcbiIsIGxwRFNFbnVtQ2FsbGJhY2ssIGxwQ29udGV4dCApOwoKCWlmICggbHBEU0VudW1DYWxsYmFjayApCgkJbHBEU0VudW1DYWxsYmFjayhOVUxMLCJXSU5FIFByaW1hcnkgU291bmQgQ2FwdHVyZSBEcml2ZXIiLAogICAgICAgICAgICAgICAgICAgICJTb3VuZENhcCIsbHBDb250ZXh0KTsKCgoJcmV0dXJuIERTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kQ2FwdHVyZUVudW1lcmF0ZVcgW0RTT1VORC44XQogKgogKiBFbnVtZXJhdGUgYWxsIERpcmVjdFNvdW5kIGRyaXZlcnMgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9JTlZBTElEUEFSQU0KICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kQ2FwdHVyZUVudW1lcmF0ZVcoCiAgICAgICAgTFBEU0VOVU1DQUxMQkFDS1cgbHBEU0VudW1DYWxsYmFjaywKICAgICAgICBMUFZPSUQgbHBDb250ZXh0KQp7CiAgICAgICAgRklYTUUoIiglcCwlcCk6c3R1YlxuIiwgbHBEU0VudW1DYWxsYmFjaywgbHBDb250ZXh0ICk7CiAgICAgICAgcmV0dXJuIERTX09LOwp9IAoKc3RhdGljIEhSRVNVTFQKRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZSggTFBWT0lEKiBwcG9iaiApCnsKCSpwcG9iaiA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCBJRGlyZWN0U291bmRDYXB0dXJlSW1wbCApICk7CgoJaWYgKCAqcHBvYmogPT0gTlVMTCApIHsKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7Cgl9CgoJewoJCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCwqcHBvYmopOwoKCQlUaGlzLT5yZWYgPSAxOwoJCUlDT01fVlRCTChUaGlzKSA9ICZkc2N2dDsKCgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCX0KCglyZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UsCglSRUZJSUQgcmlpZCwKCUxQVk9JRCogcHBvYmogKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVzLCVwKTogc3R1YlxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBvYmogKTsKCglyZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0FkZFJlZiggTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UgKQp7CglVTE9ORyB1UmVmOwogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJVFJBQ0UoICIoJXApIHdhcyAweCUwOGx4XG4iLCBUaGlzLCBUaGlzLT5yZWYgKTsKCXVSZWYgPSArKyhUaGlzLT5yZWYpOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKICAgICAgICByZXR1cm4gdVJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9SZWxlYXNlKCBMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSApCnsKCVVMT05HIHVSZWY7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKCVRSQUNFKCAiKCVwKSB3YXMgMHglMDhseFxuIiwgVGhpcywgVGhpcy0+cmVmICk7Cgl1UmVmID0gLS0oVGhpcy0+cmVmKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglpZiAoIHVSZWYgPT0gMCApIHsKCQlEZWxldGVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgkJSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMgKTsKCX0KCglyZXR1cm4gdVJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0NyZWF0ZUNhcHR1cmVCdWZmZXIoCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSwKCUxQQ0RTQ0JVRkZFUkRFU0MgbHBjRFNDQnVmZmVyRGVzYywKCUxQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSKiBscGxwRFNDYXB0dXJlQnVmZmVyLCAKCUxQVU5LTk9XTiBwVW5rICkKewoJSFJFU1VMVCBocjsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgoJVFJBQ0UoICIoJXApLT4oJXAsJXAsJXApXG4iLCBUaGlzLCBscGNEU0NCdWZmZXJEZXNjLCBscGxwRFNDYXB0dXJlQnVmZmVyLCBwVW5rICk7CgoJaWYgKCBwVW5rICkgewoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07Cgl9CgoJaHIgPSBEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKCBscGNEU0NCdWZmZXJEZXNjLCAoTFBWT0lEKilscGxwRFNDYXB0dXJlQnVmZmVyICk7CgoJcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfR2V0Q2FwcygKCUxQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlLAoJTFBEU0NDQVBTIGxwRFNDQ2FwcyApCnsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKICAgICAgICBGSVhNRSggIiglcCktPiglcCk6IHN0dWJcbiIsIFRoaXMsIGxwRFNDQ2FwcyApOwoKICAgICAgICByZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9Jbml0aWFsaXplKAoJTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UsCglMUENHVUlEIGxwY0dVSUQgKQp7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCiAgICAgICAgRklYTUUoICIoJXApLT4oJXApOiBzdHViXG4iLCBUaGlzLCBscGNHVUlEICk7CgogICAgICAgIHJldHVybiBEU19PSzsKfQoKCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRDYXB0dXJlKSBkc2N2dCA9CnsKICAgICAgICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogICAgICAgIC8qIElVbmtub3duIG1ldGhvZHMgKi8KICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9BZGRSZWYsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfUmVsZWFzZSwKCiAgICAgICAgLyogSURpcmVjdFNvdW5kQ2FwdHVyZSBtZXRob2RzICovCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfQ3JlYXRlQ2FwdHVyZUJ1ZmZlciwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9HZXRDYXBzLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0luaXRpYWxpemUgCn07CgpzdGF0aWMgSFJFU1VMVApEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKCBMUENEU0NCVUZGRVJERVNDIGxwY0RTQ0J1ZmZlckRlc2MsIExQVk9JRCogcHBvYmogKQp7CgoJRklYTUUoICIoJXAsJXApOiBpZ25vcmluZyBscGNEU0NCdWZmZXJEZXNjXG4iLCBscGNEU0NCdWZmZXJEZXNjLCBwcG9iaiApOwoKCSpwcG9iaiA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCApICk7CgoJaWYgKCAqcHBvYmogPT0gTlVMTCApIHsKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7Cgl9CgoJewoJCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCwqcHBvYmopOwoKCQlUaGlzLT5yZWYgPSAxOwoJCUlDT01fVlRCTChUaGlzKSA9ICZkc2NidnQ7CgoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7Cgl9CgoJcmV0dXJuIFNfT0s7Cn0KCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCiAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgTFBWT0lEKiBwcG9iaiApCnsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKICAgICAgICBGSVhNRSggIiglcCktPiglcywlcCk6IHN0dWJcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwb2JqICk7CgogICAgICAgIHJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfQWRkUmVmKCBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSApCnsKICAgICAgICBVTE9ORyB1UmVmOwogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgogICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKCVRSQUNFKCAiKCVwKSB3YXMgMHglMDhseFxuIiwgVGhpcywgVGhpcy0+cmVmICk7CiAgICAgICAgdVJlZiA9ICsrKFRoaXMtPnJlZik7CgogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKICAgICAgICByZXR1cm4gdVJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9SZWxlYXNlKCBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSApCnsKICAgICAgICBVTE9ORyB1UmVmOwogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgogICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKCVRSQUNFKCAiKCVwKSB3YXMgMHglMDhseFxuIiwgVGhpcywgVGhpcy0+cmVmICk7CiAgICAgICAgdVJlZiA9IC0tKFRoaXMtPnJlZik7CgogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKICAgICAgICBpZiAoIHVSZWYgPT0gMCApIHsKCQlEZWxldGVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CiAgICAgICAgICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyApOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHVSZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRDYXBzKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBEU0NCQ0FQUyBscERTQ0JDYXBzICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCk6IHN0dWJcbiIsIFRoaXMsIGxwRFNDQkNhcHMgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRDdXJyZW50UG9zaXRpb24oCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUERXT1JEIGxwZHdDYXB0dXJlUG9zaXRpb24sCglMUERXT1JEIGxwZHdSZWFkUG9zaXRpb24gKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwLCVwKTogc3R1YlxuIiwgVGhpcywgbHBkd0NhcHR1cmVQb3NpdGlvbiwgbHBkd1JlYWRQb3NpdGlvbiApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldEZvcm1hdCgKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQV0FWRUZPUk1BVEVYIGxwd2Z4Rm9ybWF0LCAKCURXT1JEIGR3U2l6ZUFsbG9jYXRlZCwgCglMUERXT1JEIGxwZHdTaXplV3JpdHRlbiApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXAsMHglMDhseCwlcCk6IHN0dWJcbiIsIFRoaXMsIGxwd2Z4Rm9ybWF0LCBkd1NpemVBbGxvY2F0ZWQsIGxwZHdTaXplV3JpdHRlbiApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldFN0YXR1cygKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQRFdPUkQgbHBkd1N0YXR1cyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXApOiBzdHViXG4iLCBUaGlzLCBscGR3U3RhdHVzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfSW5pdGlhbGl6ZSgKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQRElSRUNUU09VTkRDQVBUVVJFIGxwRFNDLCAKCUxQQ0RTQ0JVRkZFUkRFU0MgbHBjRFNDQkRlc2MgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwLCVwKTogc3R1YlxuIiwgVGhpcywgbHBEU0MsIGxwY0RTQ0JEZXNjICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfTG9jaygKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCURXT1JEIGR3UmVhZEN1c29yLCAKCURXT1JEIGR3UmVhZEJ5dGVzLCAKCUxQVk9JRCogbHBscHZBdWRpb1B0cjEsIAoJTFBEV09SRCBscGR3QXVkaW9CeXRlczEsIAoJTFBWT0lEKiBscGxwdkF1ZGlvUHRyMiwgCglMUERXT1JEIGxwZHdBdWRpb0J5dGVzMiwgCglEV09SRCBkd0ZsYWdzICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglMDhsdSwlMDhsdSwlcCwlcCwlcCwlcCwweCUwOGx4KTogc3R1YlxuIiwgVGhpcywgZHdSZWFkQ3Vzb3IsIGR3UmVhZEJ5dGVzLCBscGxwdkF1ZGlvUHRyMSwgbHBkd0F1ZGlvQnl0ZXMxLCBscGxwdkF1ZGlvUHRyMiwgbHBkd0F1ZGlvQnl0ZXMyLCBkd0ZsYWdzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfU3RhcnQoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglEV09SRCBkd0ZsYWdzICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPigweCUwOGx4KTogc3R1YlxuIiwgVGhpcywgZHdGbGFncyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1N0b3AoIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCk6IHN0dWJcbiIsIFRoaXMgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9VbmxvY2soCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUFZPSUQgbHB2QXVkaW9QdHIxLCAKCURXT1JEIGR3QXVkaW9CeXRlczEsIAoJTFBWT0lEIGxwdkF1ZGlvUHRyMiwgCglEV09SRCBkd0F1ZGlvQnl0ZXMyICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCwlMDhsdSwlcCwlMDhsdSk6IHN0dWJcbiIsIFRoaXMsIGxwdkF1ZGlvUHRyMSwgZHdBdWRpb0J5dGVzMSwgbHB2QXVkaW9QdHIyLCBkd0F1ZGlvQnl0ZXMyICk7CgoJcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIpIGRzY2J2dCA9CnsKICAgICAgICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogICAgICAgIC8qIElVbmtub3duIG1ldGhvZHMgKi8KICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9BZGRSZWYsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfUmVsZWFzZSwKCiAgICAgICAgLyogSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlciBtZXRob2RzICovCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Q2FwcywKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRDdXJyZW50UG9zaXRpb24sCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Rm9ybWF0LAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldFN0YXR1cywKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9Jbml0aWFsaXplLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0xvY2ssCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfU3RhcnQsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfU3RvcCwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9VbmxvY2sKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kIENsYXNzRmFjdG9yeQogKi8KdHlwZWRlZiBzdHJ1Y3QKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJQ2xhc3NGYWN0b3J5KTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICByZWY7Cn0gSUNsYXNzRmFjdG9yeUltcGw7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgCkRTQ0ZfUXVlcnlJbnRlcmZhY2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iaikgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCglGSVhNRSgiKCVwKS0+KCVzLCVwKSxzdHViIVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKRFNDRl9BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglyZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBEU0NGX1JlbGVhc2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CgkvKiBzdGF0aWMgY2xhc3MsIHdvbid0IGJlICBmcmVlZCAqLwoJcmV0dXJuIC0tKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBEU0NGX0NyZWF0ZUluc3RhbmNlKAoJTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsTFBVTktOT1dOIHBPdXRlcixSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwKS0+KCVwLCVzLCVwKVxuIixUaGlzLHBPdXRlcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kLCByaWlkICkgKSB7CgkJLyogRklYTUU6IHJldXNlIGFscmVhZHkgY3JlYXRlZCBkc291bmQgaWYgcHJlc2VudD8gKi8KCQlyZXR1cm4gRGlyZWN0U291bmRDcmVhdGUocmlpZCwoTFBESVJFQ1RTT1VORCopcHBvYmoscE91dGVyKTsKCX0KCXJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgRFNDRl9Mb2NrU2VydmVyKExQQ0xBU1NGQUNUT1JZIGlmYWNlLEJPT0wgZG9sb2NrKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJRklYTUUoIiglcCktPiglZCksc3R1YiFcbiIsVGhpcyxkb2xvY2spOwoJcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBEU0NGX1Z0YmwgPSB7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJRFNDRl9RdWVyeUludGVyZmFjZSwKCURTQ0ZfQWRkUmVmLAoJRFNDRl9SZWxlYXNlLAoJRFNDRl9DcmVhdGVJbnN0YW5jZSwKCURTQ0ZfTG9ja1NlcnZlcgp9OwpzdGF0aWMgSUNsYXNzRmFjdG9yeUltcGwgRFNPVU5EX0NGID0geyZEU0NGX1Z0YmwsIDEgfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERsbEdldENsYXNzT2JqZWN0IFtEU09VTkQuNF0KICogUmV0cmlldmVzIGNsYXNzIG9iamVjdCBmcm9tIGEgRExMIG9iamVjdAogKgogKiBOT1RFUwogKiAgICBEb2NzIHNheSByZXR1cm5zIFNUREFQSQogKgogKiBQQVJBTVMKICogICAgcmNsc2lkIFtJXSBDTFNJRCBmb3IgdGhlIGNsYXNzIG9iamVjdAogKiAgICByaWlkICAgW0ldIFJlZmVyZW5jZSB0byBpZGVudGlmaWVyIG9mIGludGVyZmFjZSBmb3IgY2xhc3Mgb2JqZWN0CiAqICAgIHBwdiAgICBbT10gQWRkcmVzcyBvZiB2YXJpYWJsZSB0byByZWNlaXZlIGludGVyZmFjZSBwb2ludGVyIGZvciByaWlkCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFLCBFX09VVE9GTUVNT1JZLCBFX0lOVkFMSURBUkcsCiAqICAgICAgICAgICAgIEVfVU5FWFBFQ1RFRAogKi8KRFdPUkQgV0lOQVBJIERTT1VORF9EbGxHZXRDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsUkVGSUlEIHJpaWQsTFBWT0lEICpwcHYpCnsKICAgIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCksIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdik7CiAgICBpZiAoIElzRXF1YWxDTFNJRCggJklJRF9JQ2xhc3NGYWN0b3J5LCByaWlkICkgKSB7CiAgICAJKnBwdiA9IChMUFZPSUQpJkRTT1VORF9DRjsKCUlDbGFzc0ZhY3RvcnlfQWRkUmVmKChJQ2xhc3NGYWN0b3J5KikqcHB2KTsKICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIEZJWE1FKCIoJXAsJXAsJXApOiBubyBpbnRlcmZhY2UgZm91bmQuXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCksIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdik7CiAgICByZXR1cm4gQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERsbENhblVubG9hZE5vdyBbRFNPVU5ELjNdICBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIERMTCBpcyBpbiB1c2UuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBTX0ZBTFNFCiAqLwpEV09SRCBXSU5BUEkgRFNPVU5EX0RsbENhblVubG9hZE5vdyh2b2lkKQp7CiAgICBGSVhNRSgiKHZvaWQpOiBzdHViXG4iKTsKICAgIHJldHVybiBTX0ZBTFNFOwp9Cg==