LyogIAkJCURpcmVjdFNvdW5kCiAqIAogKiBDb3B5cmlnaHQgMTk5OCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggUm9iIFJpZ2dzCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzLCBJbmMuCiAqLwovKgogKiBNb3N0IHRocmVhZCBsb2NraW5nIGlzIGNvbXBsZXRlLiBUaGVyZSBtYXkgYmUgYSBmZXcgcmFjZQogKiBjb25kaXRpb25zIHN0aWxsIGx1cmtpbmcuCiAqCiAqIFRlc3RlZCB3aXRoIGEgU291bmRibGFzdGVyIGNsb25lLCBhIEdyYXZpcyBVbHRyYVNvdW5kIENsYXNzaWMsCiAqIGFuZCBhIFR1cnRsZSBCZWFjaCBUcm9wZXorLgogKgogKiBUT0RPOgogKglJbXBsZW1lbnQgRGlyZWN0U291bmRDYXB0dXJlIEFQSQogKglJbXBsZW1lbnQgU2V0Q29vcGVyYXRpdmVMZXZlbCBwcm9wZXJseSAobmVlZCB0byBhZGRyZXNzIGZvY3VzIGlzc3VlcykKICoJSW1wbGVtZW50IERpcmVjdFNvdW5kM0RCdWZmZXJzIChzdHVicyBpbiBwbGFjZSkKICoJVXNlIGhhcmR3YXJlIDNEIHN1cHBvcnQgaWYgYXZhaWxhYmxlCiAqICAgICAgQWRkIGNyaXRpY2FsIHNlY3Rpb24gbG9ja2luZyBpbnNpZGUgUmVsZWFzZSBhbmQgQWRkUmVmIG1ldGhvZHMKICogICAgICBIYW5kbGUgc3RhdGljIGJ1ZmZlcnMgLSBwdXQgdGhvc2UgaW4gaGFyZHdhcmUsIG5vbi1zdGF0aWMgbm90IGluIGhhcmR3YXJlCiAqICAgICAgSGFyZHdhcmUgRHVwbGljYXRlU291bmRCdWZmZXIKICogICAgICBQcm9wZXIgdm9sdW1lIGNhbGN1bGF0aW9uLCBhbmQgc2V0dGluZyB2b2x1bWUgaW4gSEVMIHByaW1hcnkgYnVmZmVyCiAqICAgICAgT3B0aW1pemUgV0lOTU0gYW5kIG5lZ290aWF0ZSBmcmFnbWVudCBzaXplLCBkZWNyZWFzZSBEU19IRUxfTUFSR0lOCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPG1hdGguaD4JLyogSW5zb21uaWEgLSBwb3coKSBmdW5jdGlvbiAqLwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgIm1tZGRrLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmRlZjE2LmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJkc291bmQuaCIKI2luY2x1ZGUgImRzZHJpdmVyLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwoZHNvdW5kKTsKCi8qIHRoZXNlIGFyZSBlbGlnaWJsZSBmb3IgdHVuaW5nLi4uIHRoZXkgbXVzdCBiZSBoaWdoIG9uIHNsb3cgbWFjaGluZXMuLi4gKi8KLyogZXNwZWNpYWxseSBzaW5jZSB0aGUgV0lOTU0gb3ZlcmhlYWQgaXMgcHJldHR5IGhpZ2gsIGFuZCBjb3VsZCBiZSBpbXByb3ZlZCBxdWl0ZSBhIGJpdDsKICogdGhlIGhpZ2ggRFNfSEVMX01BUkdJTiByZWZsZWN0cyB0aGUgY3VycmVudGx5IGhpZ2ggd2luZW9zcy9IRUwgbGF0ZW5jeQogKiBzb21lIHNldHRpbmdzIGhlcmUgc2hvdWxkIHByb2JhYmx5IGdldCBwb3J0ZWQgdG8gd2luZS5jb25mICovCiNkZWZpbmUgRFNfRU1VTERSSVZFUiAxIC8qIHNvbWUgZ2FtZXMgKFF1YWtlIDIsIFVUKSByZWZ1c2UgdG8gYWNjZXB0CgkJCQllbXVsYXRlZCBkc291bmQgZGV2aWNlcy4gc2V0IHRvIDAgISAqLyAKI2RlZmluZSBEU19IRUxfRlJBR1MgNDggLyogSEVMIG9ubHk6IG51bWJlciBvZiB3YXZlT3V0IGZyYWdtZW50cyBpbiBwcmltYXJ5IGJ1ZmZlciAqLwojZGVmaW5lIERTX0hFTF9NQVJHSU4gNCAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIG1peCBpbiBuZXcgYnVmZmVycyAqLwoKI2RlZmluZSBEU19TTkRfUVVFVUUgMjggLyogbWF4IG51bWJlciBvZiBmcmFnbWVudHMgdG8gcHJlYnVmZmVyICovCgovKiBMaW51eCBkb2VzIG5vdCBzdXBwb3J0IGJldHRlciB0aW1pbmcgdGhhbiAxMG1zICovCiNkZWZpbmUgRFNfVElNRV9SRVMgMTAgIC8qIFJlc29sdXRpb24gb2YgbXVsdGltZWRpYSB0aW1lciAqLwojZGVmaW5lIERTX1RJTUVfREVMIDEwICAvKiBEZWxheSBvZiBtdWx0aW1lZGlhIHRpbWVyIGNhbGxiYWNrLCBhbmQgZHVyYXRpb24gb2YgSEVMIGZyYWdtZW50ICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUHJlZGVjbGFyZSB0aGUgaW50ZXJmYWNlIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZXMKICovCnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZEltcGwgSURpcmVjdFNvdW5kSW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kQnVmZmVySW1wbCBJRGlyZWN0U291bmRCdWZmZXJJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmROb3RpZnlJbXBsIElEaXJlY3RTb3VuZE5vdGlmeUltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmQzREJ1ZmZlckltcGwgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRDYXB0dXJlSW1wbCBJRGlyZWN0U291bmRDYXB0dXJlSW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGw7CnR5cGVkZWYgc3RydWN0IElLc1Byb3BlcnR5U2V0SW1wbCBJS3NQcm9wZXJ0eVNldEltcGw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZEltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmQpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kSW1wbCBmaWVsZHMgKi8KICAgIFBJRFNEUklWRVIgICAgICAgICAgICAgICAgICBkcml2ZXI7CiAgICBEU0RSSVZFUkRFU0MgICAgICAgICAgICAgICAgZHJ2ZGVzYzsKICAgIERTRFJJVkVSQ0FQUyAgICAgICAgICAgICAgICBkcnZjYXBzOwogICAgSFdBVkVPVVQgICAgICAgICAgICAgICAgICAgIGh3bzsKICAgIExQV0FWRUhEUiAgICAgICAgICAgICAgICAgICBwd2F2ZVtEU19IRUxfRlJBR1NdOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVySUQsIHB3cGxheSwgcHd3cml0ZSwgcHdxdWV1ZTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBmcmFnbGVuOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIHByaW9sZXZlbDsKICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICBucm9mYnVmZmVyczsKICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKiAgICBidWZmZXJzOwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogICAgIHByaW1hcnk7CiAgICBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCogbGlzdGVuZXI7CiAgICBXQVZFRk9STUFURVggICAgICAgICAgICAgICAgd2Z4OyAvKiBjdXJyZW50IG1haW4gd2F2ZWZvcm1hdCAqLwogICAgQ1JJVElDQUxfU0VDVElPTgkJbG9jazsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmRCdWZmZXIgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kQnVmZmVySW1wbAp7CiAgICAvKiBGSVhNRTogZG9jdW1lbnQgKi8KICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kQnVmZmVyKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIC8qIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgZmllbGRzICovCiAgICBQSURTRFJJVkVSQlVGRkVSICAgICAgICAgIGh3YnVmOwogICAgV0FWRUZPUk1BVEVYICAgICAgICAgICAgICB3Zng7CiAgICBMUEJZVEUgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjsKICAgIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCogZHMzZGI7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIHBsYXlmbGFncyxzdGF0ZSxsZWFkaW47CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIHBsYXlwb3Msc3RhcnRwb3Msd3JpdGVsZWFkLGJ1ZmxlbjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgbkF2Z0J5dGVzUGVyU2VjOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBmcmVxOwogICAgRFNWT0xVTUVQQU4gICAgICAgICAgICAgICB2b2xwYW47CiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiAgIHBhcmVudDsgICAgICAgICAvKiBmb3IgZHVwbGljYXRlcyAqLwogICAgSURpcmVjdFNvdW5kSW1wbCogICAgICAgICBkc291bmQ7CiAgICBEU0JVRkZFUkRFU0MgICAgICAgICAgICAgIGRzYmQ7CiAgICBMUERTQlBPU0lUSU9OTk9USUZZICAgICAgIG5vdGlmaWVzOwogICAgaW50ICAgICAgICAgICAgICAgICAgICAgICBucm9mbm90aWZpZXM7CiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICAgIGxvY2s7CiAgICAvKiB1c2VkIGZvciBmcmVxdWVuY3kgY29udmVyc2lvbiAoUGVyZmVjdFBpdGNoKSAqLwogICAgVUxPTkcgICAgICAgICAgICAgICAgICAgICBmcmVxQWRqdXN0LCBmcmVxQWNjOwogICAgLyogdXNlZCBmb3IgaW50ZWxsaWdlbnQgKHdlbGwsIHNvcnQgb2YpIHByZWJ1ZmZlcmluZyAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBwcm9iYWJseV92YWxpZF90bzsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgcHJpbWFyeV9taXhwb3MsIGJ1Zl9taXhwb3M7Cn07CgojZGVmaW5lIFNUQVRFX1NUT1BQRUQgIDAKI2RlZmluZSBTVEFURV9TVEFSVElORyAxCiNkZWZpbmUgU1RBVEVfUExBWUlORyAgMgojZGVmaW5lIFNUQVRFX1NUT1BQSU5HIDMKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmROb3RpZnkgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kTm90aWZ5SW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZE5vdGlmeSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmROb3RpZnlJbXBsIGZpZWxkcyAqLwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogZHNiOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJRGlyZWN0U291bmQzRExpc3RlbmVyIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kM0RMaXN0ZW5lcik7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwgZmllbGRzICovCiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBkc2I7CiAgICBEUzNETElTVEVORVIgICAgICAgICAgICBkczNkbDsKICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7ICAgCn07CgpzdHJ1Y3QgSUtzUHJvcGVydHlTZXRJbXBsIAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElLc1Byb3BlcnR5U2V0KTsKICAgIERXT1JECQkJcmVmOwogICAgLyogSUtzUHJvcGVydHlTZXRJbXBsIGZpZWxkcyAqLwogICAgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsCSpkczNkYjsJLyogYmFja3B0ciwgbm8gcmVmICovCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kM0RCdWZmZXIgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kM0RCdWZmZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmQzREJ1ZmZlckltcGwgZmllbGRzICovCiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBkc2I7CiAgICBEUzNEQlVGRkVSICAgICAgICAgICAgICBkczNkYjsKICAgIExQQllURSAgICAgICAgICAgICAgICAgIGJ1ZmZlcjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgIGJ1ZmxlbjsKICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7CiAgICBJS3NQcm9wZXJ0eVNldEltcGwqICAgICBpa3M7Cn07CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZENhcHR1cmUgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmRDYXB0dXJlKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwoKICAgIC8qIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsIGZpZWxkcyAqLwogICAgQ1JJVElDQUxfU0VDVElPTiAgICAgICAgbG9jazsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmRDYXB0dXJlIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlcik7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKCiAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCBmaWVsZHMgKi8KICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7Cn07CgoKLyogI2RlZmluZSBVU0VfRFNPVU5EM0QgMSAqLwoKI2RlZmluZSBEU09VTkRfRlJFUVNISUZUICgxNCkKCnN0YXRpYyBJRGlyZWN0U291bmRJbXBsKglkc291bmQgPSBOVUxMOwoKc3RhdGljIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqCXByaW1hcnlidWYgPSBOVUxMOwoKc3RhdGljIHZvaWQgRFNPVU5EX0NoZWNrRXZlbnQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBpbnQgbGVuKTsKCnN0YXRpYyBIUkVTVUxUIERTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmUoIExQVk9JRCogcHBvYmogKTsKc3RhdGljIEhSRVNVTFQgRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlciggTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCdWZmZXJEZXNjLCBMUFZPSUQqIHBwb2JqICk7CgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZSkgZHNjdnQ7CnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKSBkc2NidnQ7CgpzdGF0aWMgSFJFU1VMVCBtbUVycihVSU5UIGVycikKewoJc3dpdGNoKGVycikgewoJY2FzZSBNTVNZU0VSUl9OT0VSUk9SOgoJCXJldHVybiBEU19PSzsKCWNhc2UgTU1TWVNFUlJfQUxMT0NBVEVEOgoJCXJldHVybiBEU0VSUl9BTExPQ0FURUQ7CgljYXNlIE1NU1lTRVJSX0lOVkFMSEFORExFOgoJCXJldHVybiBEU0VSUl9HRU5FUklDOyAvKiBGSVhNRSAqLwoJY2FzZSBNTVNZU0VSUl9OT0RSSVZFUjoKCQlyZXR1cm4gRFNFUlJfTk9EUklWRVI7CgljYXNlIE1NU1lTRVJSX05PTUVNOgoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCWNhc2UgTU1TWVNFUlJfSU5WQUxQQVJBTToKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJZGVmYXVsdDoKCQlGSVhNRSgiVW5rbm93biBNTVNZUyBlcnJvciAlZFxuIixlcnIpOwoJCXJldHVybiBEU0VSUl9HRU5FUklDOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kRW51bWVyYXRlQSBbRFNPVU5ELjJdICAKICoKICogRW51bWVyYXRlIGFsbCBEaXJlY3RTb3VuZCBkcml2ZXJzIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfSU5WQUxJRFBBUkFNCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZEVudW1lcmF0ZUEoCglMUERTRU5VTUNBTExCQUNLQSBscERTRW51bUNhbGxiYWNrLAoJTFBWT0lEIGxwQ29udGV4dCkKewoJVFJBQ0UoImxwRFNFbnVtQ2FsbGJhY2sgPSAlcCwgbHBDb250ZXh0ID0gJXBcbiIsIAoJCWxwRFNFbnVtQ2FsbGJhY2ssIGxwQ29udGV4dCk7CgojaWZkZWYgSEFWRV9PU1MKCWlmIChscERTRW51bUNhbGxiYWNrICE9IE5VTEwpCgkJbHBEU0VudW1DYWxsYmFjayhOVUxMLCJXSU5FIERpcmVjdFNvdW5kIHVzaW5nIE9wZW4gU291bmQgU3lzdGVtIiwKCQkgICAgInNvdW5kIixscENvbnRleHQpOwojZW5kaWYKCglyZXR1cm4gRFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRFbnVtZXJhdGVXIFtEU09VTkQuM10gIAogKgogKiBFbnVtZXJhdGUgYWxsIERpcmVjdFNvdW5kIGRyaXZlcnMgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9JTlZBTElEUEFSQU0KICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kRW51bWVyYXRlVygKCUxQRFNFTlVNQ0FMTEJBQ0tXIGxwRFNFbnVtQ2FsbGJhY2ssIAoJTFBWT0lEIGxwQ29udGV4dCApCnsKICAgICAgICBGSVhNRSgibHBEU0VudW1DYWxsYmFjayA9ICVwLCBscENvbnRleHQgPSAlcDogc3R1YlxuIiwgCiAgICAgICAgICAgICAgICBscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQpOwoKICAgICAgICByZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgdm9pZCBfZHVtcF9EU0JDQVBTKERXT1JEIHhtYXNrKSB7CglzdHJ1Y3QgewoJCURXT1JECW1hc2s7CgkJY2hhcgkqbmFtZTsKCX0gZmxhZ3NbXSA9IHsKI2RlZmluZSBGRSh4KSB7IHgsICN4IH0sCgkJRkUoRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCUZFKERTQkNBUFNfU1RBVElDKQoJCUZFKERTQkNBUFNfTE9DSEFSRFdBUkUpCgkJRkUoRFNCQ0FQU19MT0NTT0ZUV0FSRSkKCQlGRShEU0JDQVBTX0NUUkwzRCkKCQlGRShEU0JDQVBTX0NUUkxGUkVRVUVOQ1kpCgkJRkUoRFNCQ0FQU19DVFJMUEFOKQoJCUZFKERTQkNBUFNfQ1RSTFZPTFVNRSkKCQlGRShEU0JDQVBTX0NUUkxQT1NJVElPTk5PVElGWSkKCQlGRShEU0JDQVBTX0NUUkxERUZBVUxUKQoJCUZFKERTQkNBUFNfQ1RSTEFMTCkKCQlGRShEU0JDQVBTX1NUSUNLWUZPQ1VTKQoJCUZFKERTQkNBUFNfR0xPQkFMRk9DVVMpCgkJRkUoRFNCQ0FQU19HRVRDVVJSRU5UUE9TSVRJT04yKQoJCUZFKERTQkNBUFNfTVVURTNEQVRNQVhESVNUQU5DRSkKI3VuZGVmIEZFCgl9OwoJaW50CWk7CgoJZm9yIChpPTA7aTxzaXplb2YoZmxhZ3MpL3NpemVvZihmbGFnc1swXSk7aSsrKQoJCWlmICgoZmxhZ3NbaV0ubWFzayAmIHhtYXNrKSA9PSBmbGFnc1tpXS5tYXNrKQoJCQlEUFJJTlRGKCIlcyAiLGZsYWdzW2ldLm5hbWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgSUtzUHJvcGVydHlTZXQKICovCgovKiBJVW5rbm93biBtZXRob2RzICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfUXVlcnlJbnRlcmZhY2UoCglMUEtTUFJPUEVSVFlTRVQgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlcCksIHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9BZGRSZWYoTFBLU1BST1BFUlRZU0VUIGlmYWNlKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglUaGlzLT5yZWYrKzsKCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX1JlbGVhc2UoTFBLU1BST1BFUlRZU0VUIGlmYWNlKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglUaGlzLT5yZWYtLTsKCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfR2V0KExQS1NQUk9QRVJUWVNFVCBpZmFjZSwKCVJFRkdVSUQgZ3VpZFByb3BTZXQsIFVMT05HIGR3UHJvcElELAoJTFBWT0lEIHBJbnN0YW5jZURhdGEsIFVMT05HIGNiSW5zdGFuY2VEYXRhLAoJTFBWT0lEIHBQcm9wRGF0YSwgVUxPTkcgY2JQcm9wRGF0YSwKCVBVTE9ORyBwY2JSZXR1cm5lZAopIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJXMsJWxkLCVwLCVsZCwlcCwlbGQsJXApLCBzdHViIVxuIixUaGlzLGRlYnVnc3RyX2d1aWQoZ3VpZFByb3BTZXQpLGR3UHJvcElELHBJbnN0YW5jZURhdGEsY2JJbnN0YW5jZURhdGEscFByb3BEYXRhLGNiUHJvcERhdGEscGNiUmV0dXJuZWQpOwoJcmV0dXJuIEVfUFJPUF9JRF9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9TZXQoTFBLU1BST1BFUlRZU0VUIGlmYWNlLAoJUkVGR1VJRCBndWlkUHJvcFNldCwgVUxPTkcgZHdQcm9wSUQsCglMUFZPSUQgcEluc3RhbmNlRGF0YSwgVUxPTkcgY2JJbnN0YW5jZURhdGEsCglMUFZPSUQgcFByb3BEYXRhLCBVTE9ORyBjYlByb3BEYXRhCikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlbGQsJXAsJWxkLCVwLCVsZCksIHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChndWlkUHJvcFNldCksZHdQcm9wSUQscEluc3RhbmNlRGF0YSxjYkluc3RhbmNlRGF0YSxwUHJvcERhdGEsY2JQcm9wRGF0YSk7CglyZXR1cm4gRV9QUk9QX0lEX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX1F1ZXJ5U3VwcG9ydChMUEtTUFJPUEVSVFlTRVQgaWZhY2UsCglSRUZHVUlEIGd1aWRQcm9wU2V0LCBVTE9ORyBkd1Byb3BJRCwgUFVMT05HIHBUeXBlU3VwcG9ydAopIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJXMsJWxkLCVwKSwgc3R1YiFcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKGd1aWRQcm9wU2V0KSxkd1Byb3BJRCxwVHlwZVN1cHBvcnQpOwoJcmV0dXJuIEVfUFJPUF9JRF9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElLc1Byb3BlcnR5U2V0KSBpa3N2dCA9IHsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglJS3NQcm9wZXJ0eVNldEltcGxfUXVlcnlJbnRlcmZhY2UsCglJS3NQcm9wZXJ0eVNldEltcGxfQWRkUmVmLAoJSUtzUHJvcGVydHlTZXRJbXBsX1JlbGVhc2UsCglJS3NQcm9wZXJ0eVNldEltcGxfR2V0LAoJSUtzUHJvcGVydHlTZXRJbXBsX1NldCwKCUlLc1Byb3BlcnR5U2V0SW1wbF9RdWVyeVN1cHBvcnQKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBJRGlyZWN0U291bmQzREJ1ZmZlcgogKi8KCi8qIElVbmtub3duIG1ldGhvZHMgKi8KI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcG9iaikKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCxpZmFjZSk7CgoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JS3NQcm9wZXJ0eVNldCwgcmlpZCApICkgewoJICAgIElEaXJlY3RTb3VuZDNEQnVmZmVyX0FkZFJlZihpZmFjZSk7CgkgICAgKnBwb2JqID0gVGhpcy0+aWtzOwoJICAgIHJldHVybiBTX09LOwoJfQoKCUZJWE1FKCIoJXAsJXMsJXApLCBubyBzdWNoIGludGVyZmFjZS5cbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX0ZBSUw7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoJVGhpcy0+cmVmKys7CglyZXR1cm4gVGhpcy0+cmVmOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGRcbiIsIFRoaXMsIFRoaXMtPnJlZik7CgoJaWYoLS1UaGlzLT5yZWYpCgkJcmV0dXJuIFRoaXMtPnJlZjsKCglpZiAoVGhpcy0+ZHNiKQoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKVRoaXMtPmRzYik7CgoJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCZUaGlzLT5sb2NrKTsKCglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+YnVmZmVyKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCglyZXR1cm4gMDsKfQojZW5kaWYKCi8qIElEaXJlY3RTb3VuZDNEQnVmZmVyIG1ldGhvZHMgKi8KI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldEFsbFBhcmFtZXRlcnMoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUERTM0RCVUZGRVIgbHBEczNkQnVmZmVyKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZUFuZ2xlcygKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRFdPUkQgbHBkd0luc2lkZUNvbmVBbmdsZSwKCUxQRFdPUkQgbHBkd091dHNpZGVDb25lQW5nbGUpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3JpZW50YXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUEQzRFZFQ1RPUiBscHZDb25lT3JpZW50YXRpb24pCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3V0c2lkZVZvbHVtZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQTE9ORyBscGxDb25lT3V0c2lkZVZvbHVtZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldE1heERpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWQUxVRSBscGZNYXhEaXN0YW5jZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldE1pbkRpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWQUxVRSBscGZNaW5EaXN0YW5jZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldE1vZGUoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUERXT1JEIGxwZHdNb2RlKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0UG9zaXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUEQzRFZFQ1RPUiBscHZQb3NpdGlvbikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFZlbG9jaXR5KAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2VmVsb2NpdHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBDRFMzREJVRkZFUiBscGNEczNkQnVmZmVyLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVBbmdsZXMoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEV09SRCBkd0luc2lkZUNvbmVBbmdsZSwKCURXT1JEIGR3T3V0c2lkZUNvbmVBbmdsZSwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lT3JpZW50YXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSB4LCBEM0RWQUxVRSB5LCBEM0RWQUxVRSB6LAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVPdXRzaWRlVm9sdW1lKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTE9ORyBsQ29uZU91dHNpZGVWb2x1bWUsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWF4RGlzdGFuY2UoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSBmTWF4RGlzdGFuY2UsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWluRGlzdGFuY2UoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSBmTWluRGlzdGFuY2UsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TW9kZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCURXT1JEIGR3TW9kZSwKCURXT1JEIGR3QXBwbHkpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIm1vZGUgPSAlbHhcbiIsIGR3TW9kZSk7CglUaGlzLT5kczNkYi5kd01vZGUgPSBkd01vZGU7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0UG9zaXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSB4LCBEM0RWQUxVRSB5LCBEM0RWQUxVRSB6LAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldFZlbG9jaXR5KAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZDNEQnVmZmVyKSBkczNkYnZ0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCgkvKiBJVW5rbm93biBtZXRob2RzICovCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfQWRkUmVmLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1JlbGVhc2UsCgkvKiBJRGlyZWN0U291bmQzREJ1ZmZlciBtZXRob2RzICovCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0QWxsUGFyYW1ldGVycywKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lQW5nbGVzLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldENvbmVPcmllbnRhdGlvbiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3V0c2lkZVZvbHVtZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNYXhEaXN0YW5jZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNaW5EaXN0YW5jZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNb2RlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFBvc2l0aW9uLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFZlbG9jaXR5LAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldEFsbFBhcmFtZXRlcnMsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZUFuZ2xlcywKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lT3JpZW50YXRpb24sCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZU91dHNpZGVWb2x1bWUsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWF4RGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWluRGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TW9kZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRWZWxvY2l0eSwKfTsKI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBpbnQgRFNPVU5EX0NyZWF0ZTNEQnVmZmVyKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqIGRzYikKewoJRFdPUkQJaSwgdGVtcCwgaVNpemUsIG9TaXplLCBvZmZzZXQ7CglMUEJZVEUJYklidWYsIGJPYnVmLCBiVGJ1ZiA9IE5VTEw7CglMUFdPUkQJd0lidWYsIHdPYnVmLCB3VGJ1ZiA9IE5VTEw7CgoJLyogSW5zaWRlIERpcmVjdFggc2F5cyBpdCdzIHN0dXBpZCBidXQgYWxsb3dlZCAqLwoJaWYgKGRzYi0+d2Z4Lm5DaGFubmVscyA9PSAyKSB7CgkJLyogQ29udmVydCB0byBtb25vICovCgkJaWYgKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSB7CgkJCWlTaXplID0gZHNiLT5idWZsZW4gLyA0OwoJCQl3VGJ1ZiA9IG1hbGxvYyhkc2ItPmJ1ZmxlbiAvIDIpOwoJCQlpZiAod1RidWYgPT0gTlVMTCkKCQkJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCQkJZm9yIChpID0gMDsgaSA8IGlTaXplOyBpKyspCgkJCQl3VGJ1ZltpXSA9IChkc2ItPmJ1ZmZlcltpICogMl0gKyBkc2ItPmJ1ZmZlclsoaSAqIDIpICsgMV0pIC8gMjsKCQkJd0lidWYgPSB3VGJ1ZjsKCQl9IGVsc2UgewoJCQlpU2l6ZSA9IGRzYi0+YnVmbGVuIC8gMjsKCQkJYlRidWYgPSBtYWxsb2MoZHNiLT5idWZsZW4gLyAyKTsKCQkJaWYgKGJUYnVmID09IE5VTEwpCgkJCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgkJCWZvciAoaSA9IDA7IGkgPCBpU2l6ZTsgaSsrKQoJCQkJYlRidWZbaV0gPSAoZHNiLT5idWZmZXJbaSAqIDJdICsgZHNiLT5idWZmZXJbKGkgKiAyKSArIDFdKSAvIDI7CgkJCWJJYnVmID0gYlRidWY7CgkJfQoJfSBlbHNlIHsKCQlpZiAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpIHsKCQkJaVNpemUgPSBkc2ItPmJ1ZmxlbiAvIDI7CgkJCXdJYnVmID0gKExQV09SRCkgZHNiLT5idWZmZXI7CgkJfSBlbHNlIHsKCQkJYklidWYgPSAoTFBCWVRFKSBkc2ItPmJ1ZmZlcjsKCQkJaVNpemUgPSBkc2ItPmJ1ZmxlbjsKCQl9Cgl9CgoJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgewoJCXdPYnVmID0gKExQV09SRCkgZHNiLT5kczNkYi0+YnVmZmVyOwoJCW9TaXplID0gZHNiLT5kczNkYi0+YnVmbGVuIC8gMjsKCX0gZWxzZSB7CgkJYk9idWYgPSAoTFBCWVRFKSBkc2ItPmRzM2RiLT5idWZmZXI7CgkJb1NpemUgPSBkc2ItPmRzM2RiLT5idWZsZW47Cgl9CgoJb2Zmc2V0ID0gcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjIC8gMTAwOwkJLyogMTBtcyAqLwoJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNiAmJiBkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikKCQlmb3IgKGkgPSAwOyBpIDwgaVNpemU7IGkrKykgewoJCQl0ZW1wID0gd0lidWZbaV07CgkJCWlmIChpID49IG9mZnNldCkKCQkJCXRlbXAgKz0gd0lidWZbaSAtIG9mZnNldF0gPj4gOTsKCQkJZWxzZQoJCQkJdGVtcCArPSB3SWJ1ZltpICsgaVNpemUgLSBvZmZzZXRdID4+IDk7CgkJCXdPYnVmW2kgKiAyXSA9IHRlbXA7CgkJCXdPYnVmWyhpICogMikgKyAxXSA9IHRlbXA7CgkJfQoJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDggJiYgZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCkKCQlmb3IgKGkgPSAwOyBpIDwgaVNpemU7IGkrKykgewoJCQl0ZW1wID0gYklidWZbaV07CgkJCWlmIChpID49IG9mZnNldCkKCQkJCXRlbXAgKz0gYklidWZbaSAtIG9mZnNldF0gPj4gNTsKCQkJZWxzZQoJCQkJdGVtcCArPSBiSWJ1ZltpICsgaVNpemUgLSBvZmZzZXRdID4+IDU7CgkJCWJPYnVmW2kgKiAyXSA9IHRlbXA7CgkJCWJPYnVmWyhpICogMikgKyAxXSA9IHRlbXA7CgkJfQoJCglpZiAod1RidWYpCgkJZnJlZSh3VGJ1Zik7CglpZiAoYlRidWYpCgkJZnJlZShiVGJ1Zik7CgoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lcgogKi8KCi8qIElVbmtub3duIG1ldGhvZHMgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXAsJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CgkKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCxpZmFjZSk7CglUaGlzLT5yZWYrKzsKCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfUmVsZWFzZShMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSkKewoJVUxPTkcgdWxSZXR1cm47CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKCXVsUmV0dXJuID0gLS1UaGlzLT5yZWY7CgoJLyogRnJlZSBhbGwgcmVzb3VyY2VzICovCglpZiggdWxSZXR1cm4gPT0gMCApIHsKCQlpZihUaGlzLT5kc2IpCgkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKVRoaXMtPmRzYik7CgkJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCZUaGlzLT5sb2NrKTsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7Cgl9CgoJcmV0dXJuIHVsUmV0dXJuOwp9CgovKiBJRGlyZWN0U291bmQzRExpc3RlbmVyIG1ldGhvZHMgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldEFsbFBhcmFtZXRlcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEUzNETElTVEVORVIgbHBEUzNETCkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0RGlzdGFuY2VGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmRGlzdGFuY2VGYWN0b3IpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldERvcHBsZXJGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmRG9wcGxlckZhY3RvcikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0T3JpZW50YXRpb24oCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkVDVE9SIGxwdk9yaWVudEZyb250LAoJTFBEM0RWRUNUT1IgbHB2T3JpZW50VG9wKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRQb3NpdGlvbigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2UG9zaXRpb24pCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldFJvbGxvZmZGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmUm9sbG9mZkZhY3RvcikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0VmVsb2NpdHkoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkVDVE9SIGxwdlZlbG9jaXR5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUENEUzNETElTVEVORVIgbHBjRFMzREwsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXREaXN0YW5jZUZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgZkRpc3RhbmNlRmFjdG9yLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0RG9wcGxlckZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgZkRvcHBsZXJGYWN0b3IsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRPcmllbnRhdGlvbigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgeEZyb250LCBEM0RWQUxVRSB5RnJvbnQsIEQzRFZBTFVFIHpGcm9udCwKCUQzRFZBTFVFIHhUb3AsIEQzRFZBTFVFIHlUb3AsIEQzRFZBTFVFIHpUb3AsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRQb3NpdGlvbigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFJvbGxvZmZGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIGZSb2xsb2ZmRmFjdG9yLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0VmVsb2NpdHkoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIHgsIEQzRFZBTFVFIHksIEQzRFZBTFVFIHosCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9Db21taXREZWZlcnJlZFNldHRpbmdzKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UpCgp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmQzRExpc3RlbmVyKSBkczNkbHZ0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCgkvKiBJVW5rbm93biBtZXRob2RzICovCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9RdWVyeUludGVyZmFjZSwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1JlbGVhc2UsCgkvKiBJRGlyZWN0U291bmQzRExpc3RlbmVyIG1ldGhvZHMgKi8KCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldEFsbFBhcmFtZXRlciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldERpc3RhbmNlRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0RG9wcGxlckZhY3RvciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldE9yaWVudGF0aW9uLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0UG9zaXRpb24sCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRSb2xsb2ZmRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0VmVsb2NpdHksCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0RGlzdGFuY2VGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXREb3BwbGVyRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0T3JpZW50YXRpb24sCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFJvbGxvZmZGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRWZWxvY2l0eSwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0NvbW1pdERlZmVycmVkU2V0dGluZ3MsCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSURpcmVjdFNvdW5kTm90aWZ5CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkROT1RJRlkgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iagopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmROb3RpZnlJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoJcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmROb3RpZnlJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5ETk9USUZZIGlmYWNlKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kTm90aWZ5SW1wbCxpZmFjZSk7CglyZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmROb3RpZnlJbXBsX1JlbGVhc2UoTFBESVJFQ1RTT1VORE5PVElGWSBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZE5vdGlmeUltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKCVRoaXMtPnJlZi0tOwoJaWYgKCFUaGlzLT5yZWYpIHsKCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5kc2IpOwoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmROb3RpZnlJbXBsX1NldE5vdGlmaWNhdGlvblBvc2l0aW9ucygKCUxQRElSRUNUU09VTkROT1RJRlkgaWZhY2UsRFdPUkQgaG93bXVjaCxMUENEU0JQT1NJVElPTk5PVElGWSBub3RpZnkKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kTm90aWZ5SW1wbCxpZmFjZSk7CglpbnQJaTsKCglpZiAoVFJBQ0VfT04oZHNvdW5kKSkgewoJICAgIFRSQUNFKCIoJXAsMHglMDhseCwlcClcbiIsVGhpcyxob3dtdWNoLG5vdGlmeSk7CgkgICAgZm9yIChpPTA7aTxob3dtdWNoO2krKykKCQkgICAgVFJBQ0UoIm5vdGlmeSBhdCAlbGQgdG8gMHglMDhseFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeVtpXS5kd09mZnNldCwoRFdPUkQpbm90aWZ5W2ldLmhFdmVudE5vdGlmeSk7Cgl9CglUaGlzLT5kc2ItPm5vdGlmaWVzID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLFRoaXMtPmRzYi0+bm90aWZpZXMsKFRoaXMtPmRzYi0+bnJvZm5vdGlmaWVzK2hvd211Y2gpKnNpemVvZihEU0JQT1NJVElPTk5PVElGWSkpOwoJbWVtY3B5KAlUaGlzLT5kc2ItPm5vdGlmaWVzK1RoaXMtPmRzYi0+bnJvZm5vdGlmaWVzLAoJCW5vdGlmeSwKCQlob3dtdWNoKnNpemVvZihEU0JQT1NJVElPTk5PVElGWSkKCSk7CglUaGlzLT5kc2ItPm5yb2Zub3RpZmllcys9aG93bXVjaDsKCglyZXR1cm4gU19PSzsKfQoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZE5vdGlmeSkgZHNudnQgPSAKewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCUlEaXJlY3RTb3VuZE5vdGlmeUltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmROb3RpZnlJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZE5vdGlmeUltcGxfUmVsZWFzZSwKCUlEaXJlY3RTb3VuZE5vdGlmeUltcGxfU2V0Tm90aWZpY2F0aW9uUG9zaXRpb25zLAp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlEaXJlY3RTb3VuZEJ1ZmZlcgogKi8KCnN0YXRpYyB2b2lkIERTT1VORF9SZWNhbGNWb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewoJZG91YmxlIHRlbXA7CgoJLyogdGhlIEFtcEZhY3RvcnMgYXJlIGV4cHJlc3NlZCBpbiAxNi4xNiBmaXhlZCBwb2ludCAqLwoJdm9scGFuLT5kd1ZvbEFtcEZhY3RvciA9IChVTE9ORykgKHBvdygyLjAsIHZvbHBhbi0+bFZvbHVtZSAvIDYwMC4wKSAqIDY1NTM2KTsKCS8qIEZJWE1FOiBkd1BhbntMZWZ0fFJpZ2h0fUFtcEZhY3RvciAqLwoKCS8qIEZJWE1FOiB1c2UgY2FsY3VsYXRlZCB2b2wgYW5kIHBhbiBhbXBmYWN0b3JzICovCgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSAtICh2b2xwYW4tPmxQYW4gPiAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvciA9IChVTE9ORykgKHBvdygyLjAsIHRlbXAgLyA2MDAuMCkgKiA2NTUzNik7Cgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSArICh2b2xwYW4tPmxQYW4gPCAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB0ZW1wIC8gNjAwLjApICogNjU1MzYpOwoKCVRSQUNFKCJsZWZ0ID0gJWx4LCByaWdodCA9ICVseFxuIiwgdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3Rvciwgdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfUmVjYWxjRm9ybWF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJRFdPUkQgc3c7CgoJc3cgPSBkc2ItPndmeC5uQ2hhbm5lbHMgKiAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgLyA4KTsKCWlmICgoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpICYmIGRzYi0+aHdidWYpIHsKCQlEV09SRCBmcmFnbGVuOwoJCS8qIGxldCBmcmFnbWVudCBzaXplIGFwcHJveGltYXRlIHRoZSB0aW1lciBkZWxheSAqLwoJCWZyYWdsZW4gPSAoZHNiLT5mcmVxICogRFNfVElNRV9ERUwgLyAxMDAwKSAqIHN3OwoJCS8qIHJlZHVjZSBmcmFnbWVudCBzaXplIHVudGlsIGFuIGludGVnZXIgbnVtYmVyIG9mIHRoZW0gZml0cyBpbiB0aGUgYnVmZmVyICovCgkJLyogKEZJWE1FOiB0aGlzIG1heSBvciBtYXkgbm90IGJlIGEgZ29vZCBpZGVhKSAqLwoJCXdoaWxlIChkc2ItPmJ1ZmxlbiAlIGZyYWdsZW4pIGZyYWdsZW4gLT0gc3c7CgkJZHNiLT5kc291bmQtPmZyYWdsZW4gPSBmcmFnbGVuOwoJCVRSQUNFKCJmcmFnbGVuPSVsZFxuIiwgZHNiLT5kc291bmQtPmZyYWdsZW4pOwoJfQoJLyogY2FsY3VsYXRlIHRoZSAxMG1zIHdyaXRlIGxlYWQgKi8KCWRzYi0+d3JpdGVsZWFkID0gKGRzYi0+ZnJlcSAvIDEwMCkgKiBzdzsKfQoKc3RhdGljIEhSRVNVTFQgRFNPVU5EX1ByaW1hcnlPcGVuKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCgkvKiBhcmUgd2UgdXNpbmcgd2F2ZU91dCBzdHVmZj8gKi8KCWlmICghZHNiLT5od2J1ZikgewoJCUxQQllURSBuZXdidWY7CgkJRFdPUkQgYnVmbGVuOwoJCUhSRVNVTFQgbWVyciA9IERTX09LOwoJCS8qIFN0YXJ0IGluIHBhdXNlIG1vZGUsIHRvIGFsbG93IGJ1ZmZlcnMgdG8gZ2V0IGZpbGxlZCAqLwoJCXdhdmVPdXRQYXVzZShkc2ItPmRzb3VuZC0+aHdvKTsKCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSBkc2ItPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJZWxzZSBpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJLyogdXNlIGZyYWdtZW50cyBvZiAxMG1zICgxLzEwMHMpIGVhY2ggKHdoaWNoIHNob3VsZCBnZXQgdXMgd2l0aGluCgkJICogdGhlIGRvY3VtZW50ZWQgd3JpdGUgY3Vyc29yIGxlYWQgb2YgMTAtMTVtcykgKi8KCQlidWZsZW4gPSAoKGRzYi0+d2Z4Lm5BdmdCeXRlc1BlclNlYyAvIDEwMCkgJiB+MykgKiBEU19IRUxfRlJBR1M7CgkJVFJBQ0UoImRlc2lyZWQgYnVmbGVuPSVsZCwgb2xkIGJ1ZmZlcj0lcFxuIiwgYnVmbGVuLCBkc2ItPmJ1ZmZlcik7CgkJLyogcmVhbGxvY2F0ZSBlbXVsYXRlZCBwcmltYXJ5IGJ1ZmZlciAqLwoJCW5ld2J1ZiA9IChMUEJZVEUpSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLGRzYi0+YnVmZmVyLGJ1Zmxlbik7CgkJaWYgKG5ld2J1ZiA9PSBOVUxMKSB7CgkJCUVSUigiZmFpbGVkIHRvIGFsbG9jYXRlIHByaW1hcnkgYnVmZmVyXG4iKTsKCQkJbWVyciA9IERTRVJSX09VVE9GTUVNT1JZOwoJCQkvKiBidXQgdGhlIG9sZCBidWZmZXIgbWlnaHQgc3RpbGwgZXhpc3RzIGFuZCBtdXN0IGJlIHJlLXByZXBhcmVkICovCgkJfSBlbHNlIHsKCQkJZHNiLT5idWZmZXIgPSBuZXdidWY7CgkJCWRzYi0+YnVmbGVuID0gYnVmbGVuOwoJCX0KCQlpZiAoZHNiLT5idWZmZXIpIHsKCQkJdW5zaWduZWQgYzsKCQkJSURpcmVjdFNvdW5kSW1wbCAqZHMgPSBkc2ItPmRzb3VuZDsKCgkJCWRzLT5mcmFnbGVuID0gZHNiLT5idWZsZW4gLyBEU19IRUxfRlJBR1M7CgoJCQkvKiBwcmVwYXJlIGZyYWdtZW50IGhlYWRlcnMgKi8KCQkJZm9yIChjPTA7IGM8RFNfSEVMX0ZSQUdTOyBjKyspIHsKCQkJCWRzLT5wd2F2ZVtjXS0+bHBEYXRhID0gZHNiLT5idWZmZXIgKyBjKmRzLT5mcmFnbGVuOwoJCQkJZHMtPnB3YXZlW2NdLT5kd0J1ZmZlckxlbmd0aCA9IGRzLT5mcmFnbGVuOwoJCQkJZHMtPnB3YXZlW2NdLT5kd1VzZXIgPSAoRFdPUkQpZHNiOwoJCQkJZHMtPnB3YXZlW2NdLT5kd0ZsYWdzID0gMDsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdMb29wcyA9IDA7CgkJCQllcnIgPSBtbUVycih3YXZlT3V0UHJlcGFyZUhlYWRlcihkcy0+aHdvLGRzLT5wd2F2ZVtjXSxzaXplb2YoV0FWRUhEUikpKTsKCQkJCWlmIChlcnIgIT0gRFNfT0spIHsKCQkJCQl3aGlsZSAoYy0tKQoJCQkJCQl3YXZlT3V0VW5wcmVwYXJlSGVhZGVyKGRzLT5od28sZHMtPnB3YXZlW2NdLHNpemVvZihXQVZFSERSKSk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCgkJCWRzLT5wd3BsYXkgPSAwOwoJCQlkcy0+cHd3cml0ZSA9IDA7CgkJCWRzLT5wd3F1ZXVlID0gMDsKCQkJbWVtc2V0KGRzYi0+YnVmZmVyLCAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpID8gMCA6IDEyOCwgZHNiLT5idWZsZW4pOwoJCQlUUkFDRSgiZnJhZ2xlbj0lbGRcbiIsIGRzLT5mcmFnbGVuKTsKCQl9CgkJaWYgKChlcnIgPT0gRFNfT0spICYmIChtZXJyICE9IERTX09LKSkKCQkJZXJyID0gbWVycjsKCX0KCXJldHVybiBlcnI7Cn0KCgpzdGF0aWMgdm9pZCBEU09VTkRfUHJpbWFyeUNsb3NlKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJLyogYXJlIHdlIHVzaW5nIHdhdmVPdXQgc3R1ZmY/ICovCglpZiAoIWRzYi0+aHdidWYpIHsKCQl1bnNpZ25lZCBjOwoJCUlEaXJlY3RTb3VuZEltcGwgKmRzID0gZHNiLT5kc291bmQ7CgoJCXdhdmVPdXRSZXNldChkcy0+aHdvKTsKCQlmb3IgKGM9MDsgYzxEU19IRUxfRlJBR1M7IGMrKykKCQkJd2F2ZU91dFVucHJlcGFyZUhlYWRlcihkcy0+aHdvLCBkcy0+cHdhdmVbY10sIHNpemVvZihXQVZFSERSKSk7Cgl9Cn0KCnN0YXRpYyBIUkVTVUxUIERTT1VORF9QcmltYXJ5UGxheShJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CglpZiAoZHNiLT5od2J1ZikKCQllcnIgPSBJRHNEcml2ZXJCdWZmZXJfUGxheShkc2ItPmh3YnVmLCAwLCAwLCBEU0JQTEFZX0xPT1BJTkcpOwoJcmV0dXJuIGVycjsKfQoKc3RhdGljIEhSRVNVTFQgRFNPVU5EX1ByaW1hcnlTdG9wKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCWlmIChkc2ItPmh3YnVmKSB7CgkJZXJyID0gSURzRHJpdmVyQnVmZmVyX1N0b3AoZHNiLT5od2J1Zik7CgkJaWYgKGVyciA9PSBEU0VSUl9CVUZGRVJMT1NUKSB7CgkJCS8qIFdpbmUtb25seTogdGhlIGRyaXZlciB3YW50cyB1cyB0byByZW9wZW4gdGhlIGRldmljZSAqLwoJCQkvKiBGSVhNRTogY2hlY2sgZm9yIGVycm9ycyAqLwoJCQlJRHNEcml2ZXJCdWZmZXJfUmVsZWFzZShwcmltYXJ5YnVmLT5od2J1Zik7CgkJCXdhdmVPdXRDbG9zZShkc2ItPmRzb3VuZC0+aHdvKTsKCQkJZHNiLT5kc291bmQtPmh3byA9IDA7CgkJCXdhdmVPdXRPcGVuKCYoZHNiLT5kc291bmQtPmh3byksIGRzYi0+ZHNvdW5kLT5kcnZkZXNjLmRuRGV2Tm9kZSwKCQkJCSAgICAmKHByaW1hcnlidWYtPndmeCksIDAsIDAsIENBTExCQUNLX05VTEwgfCBXQVZFX0RJUkVDVFNPVU5EKTsKCQkJZXJyID0gSURzRHJpdmVyX0NyZWF0ZVNvdW5kQnVmZmVyKGRzYi0+ZHNvdW5kLT5kcml2ZXIsJihkc2ItPndmeCksZHNiLT5kc2JkLmR3RmxhZ3MsMCwKCQkJCQkJCSAgJihkc2ItPmJ1ZmxlbiksJihkc2ItPmJ1ZmZlciksCgkJCQkJCQkgIChMUFZPSUQpJihkc2ItPmh3YnVmKSk7CgkJfQoJfQoJcmV0dXJuIGVycjsKfQoKLyogVGhpcyBzZXRzIHRoaXMgZm9ybWF0IGZvciB0aGUgPGVtPlByaW1hcnkgQnVmZmVyIE9ubHk8L2VtPiAqLwovKiBTZWUgZmlsZTovLy9jZHJvbS9zZGs1Mi9kb2NzL3dvcmRkb2MvZHNvdW5kLmRvYyBwYWdlIDEyMCAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRGb3JtYXQoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQV0FWRUZPUk1BVEVYIHdmZXgKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogZHNiOwoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCWludAkJCWk7CgoJLyogTGV0J3MgYmUgcGVkYW50aWMhICovCglpZiAoKHdmZXggPT0gTlVMTCkgfHwKCSAgICAod2ZleC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pIHx8CgkgICAgKHdmZXgtPm5DaGFubmVscyA8IDEpIHx8ICh3ZmV4LT5uQ2hhbm5lbHMgPiAyKSB8fAoJICAgICh3ZmV4LT5uU2FtcGxlc1BlclNlYyA8IDEpIHx8CgkgICAgKHdmZXgtPm5CbG9ja0FsaWduIDwgMSkgfHwgKHdmZXgtPm5DaGFubmVscyA+IDQpIHx8CgkgICAgKCh3ZmV4LT53Qml0c1BlclNhbXBsZSAhPSA4KSAmJiAod2ZleC0+d0JpdHNQZXJTYW1wbGUgIT0gMTYpKSkgewoJCVRSQUNFKCJmYWlsZWQgcGVkYW50aWMgY2hlY2shXG4iKTsKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJfQoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7CgoJaWYgKHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYyAhPSB3ZmV4LT5uU2FtcGxlc1BlclNlYykgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyczsKCQlmb3IgKGkgPSAwOyBpIDwgZHNvdW5kLT5ucm9mYnVmZmVyczsgaSsrLCBkc2IrKykgewoJCQkvKiAqKioqICovCgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoKCpkc2IpLT5sb2NrKSk7CgoJCQkoKmRzYiktPmZyZXFBZGp1c3QgPSAoKCpkc2IpLT5mcmVxIDw8IERTT1VORF9GUkVRU0hJRlQpIC8KCQkJCXdmZXgtPm5TYW1wbGVzUGVyU2VjOwoKCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJigoKmRzYiktPmxvY2spKTsKCQkJLyogKioqKiAqLwoJCX0KCX0KCgltZW1jcHkoJihwcmltYXJ5YnVmLT53ZngpLCB3ZmV4LCBzaXplb2YocHJpbWFyeWJ1Zi0+d2Z4KSk7CgoJVFJBQ0UoIihmb3JtYXR0YWc9MHglMDR4LGNoYW5zPSVkLHNhbXBsZXJhdGU9JWxkLCIKCQkgICAiYnl0ZXNwZXJzZWM9JWxkLGJsb2NrYWxpZ249JWQsYml0c3BlcnNhbXA9JWQsY2JTaXplPSVkKVxuIiwKCQkgICB3ZmV4LT53Rm9ybWF0VGFnLCB3ZmV4LT5uQ2hhbm5lbHMsIHdmZXgtPm5TYW1wbGVzUGVyU2VjLAoJCSAgIHdmZXgtPm5BdmdCeXRlc1BlclNlYywgd2ZleC0+bkJsb2NrQWxpZ24sIAoJCSAgIHdmZXgtPndCaXRzUGVyU2FtcGxlLCB3ZmV4LT5jYlNpemUpOwoKCXByaW1hcnlidWYtPndmeC5uQXZnQnl0ZXNQZXJTZWMgPQoJCVRoaXMtPndmeC5uU2FtcGxlc1BlclNlYyAqIFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKCWlmIChwcmltYXJ5YnVmLT5kc291bmQtPmRydmRlc2MuZHdGbGFncyAmIERTRERFU0NfRE9NTVNZU1RFTVNFVEZPUk1BVCkgewoJCS8qIEZJWE1FOiBjaGVjayBmb3IgZXJyb3JzICovCgkJRFNPVU5EX1ByaW1hcnlDbG9zZShwcmltYXJ5YnVmKTsKCQl3YXZlT3V0Q2xvc2UoVGhpcy0+ZHNvdW5kLT5od28pOwoJCVRoaXMtPmRzb3VuZC0+aHdvID0gMDsKICAgICAgICAgICAgICAgIHdhdmVPdXRPcGVuKCYoVGhpcy0+ZHNvdW5kLT5od28pLCBUaGlzLT5kc291bmQtPmRydmRlc2MuZG5EZXZOb2RlLAoJCQkgICAgJihwcmltYXJ5YnVmLT53ZngpLCAwLCAwLCBDQUxMQkFDS19OVUxMIHwgV0FWRV9ESVJFQ1RTT1VORCk7CgkJRFNPVU5EX1ByaW1hcnlPcGVuKHByaW1hcnlidWYpOwoJfQoJaWYgKHByaW1hcnlidWYtPmh3YnVmKSB7CgkJZXJyID0gSURzRHJpdmVyQnVmZmVyX1NldEZvcm1hdChwcmltYXJ5YnVmLT5od2J1ZiwgJihwcmltYXJ5YnVmLT53ZngpKTsKCQlpZiAoZXJyID09IERTRVJSX0JVRkZFUkxPU1QpIHsKCQkJLyogV2luZS1vbmx5OiB0aGUgZHJpdmVyIHdhbnRzIHVzIHRvIHJlY3JlYXRlIHRoZSBIVyBidWZmZXIgKi8KCQkJSURzRHJpdmVyQnVmZmVyX1JlbGVhc2UocHJpbWFyeWJ1Zi0+aHdidWYpOwoJCQllcnIgPSBJRHNEcml2ZXJfQ3JlYXRlU291bmRCdWZmZXIocHJpbWFyeWJ1Zi0+ZHNvdW5kLT5kcml2ZXIsJihwcmltYXJ5YnVmLT53ZngpLHByaW1hcnlidWYtPmRzYmQuZHdGbGFncywwLAoJCQkJCQkJICAmKHByaW1hcnlidWYtPmJ1ZmxlbiksJihwcmltYXJ5YnVmLT5idWZmZXIpLAoJCQkJCQkJICAoTFBWT0lEKSYocHJpbWFyeWJ1Zi0+aHdidWYpKTsKCQkJaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJCWVsc2UgaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSBwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJfQoJfQoJRFNPVU5EX1JlY2FsY0Zvcm1hdChwcmltYXJ5YnVmKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmRzb3VuZC0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Vm9sdW1lKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMT05HIHZvbAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyx2b2wpOwoKCS8qIEknbSBub3Qgc3VyZSBpZiB3ZSBuZWVkIHRoaXMgZm9yIHByaW1hcnkgYnVmZmVyICovCglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpKQoJCXJldHVybiBEU0VSUl9DT05UUk9MVU5BVkFJTDsKCglpZiAoKHZvbCA+IERTQlZPTFVNRV9NQVgpIHx8ICh2b2wgPCBEU0JWT0xVTUVfTUlOKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPnZvbHBhbi5sVm9sdW1lID0gdm9sOwoKCURTT1VORF9SZWNhbGNWb2xQYW4oJihUaGlzLT52b2xwYW4pKTsKCglpZiAoVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfU2V0Vm9sdW1lUGFuKFRoaXMtPmh3YnVmLCAmKFRoaXMtPnZvbHBhbikpOwoJfQoJZWxzZSBpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CiNpZiAwIC8qIHNob3VsZCB3ZSByZWFsbHkgZG8gdGhpcz8gKi8KCQkvKiB0aGUgRFMgdm9sdW1lIHJhbmdlcyBmcm9tIDAgKG1heCwgMGRCIGF0dGVudWF0aW9uKSB0byAtMTAwMDAgKG1pbiwgMTAwZEIgYXR0ZW51YXRpb24pICovCgkJLyogdGhlIE1NIHZvbHVtZSByYW5nZXMgZnJvbSAwIHRvIDB4ZmZmZiBpbiBhbiB1bnNwZWNpZmllZCBsb2dhcml0aG1pYyBzY2FsZSAqLwoJCVdPUkQgY3ZvbCA9IDB4ZmZmZiArIHZvbCo2ICsgdm9sLzI7CgkJRFdPUkQgdm9sID0gY3ZvbCB8ICgoRFdPUkQpY3ZvbCA8PCAxNikKCQl3YXZlT3V0U2V0Vm9sdW1lKFRoaXMtPmRzb3VuZC0+aHdvLCB2b2wpOwojZW5kaWYKCX0KCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFZvbHVtZSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBMT05HIHZvbAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXApXG4iLFRoaXMsdm9sKTsKCglpZiAodm9sID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqdm9sID0gVGhpcy0+dm9scGFuLmxWb2x1bWU7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZyZXF1ZW5jeSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsRFdPUkQgZnJlcQopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJWxkKVxuIixUaGlzLGZyZXEpOwoKCS8qIFlvdSBjYW5ub3Qgc2V0IHRoZSBmcmVxdWVuY3kgb2YgdGhlIHByaW1hcnkgYnVmZmVyICovCglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxGUkVRVUVOQ1kpIHx8CgkgICAgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikpCgkJcmV0dXJuIERTRVJSX0NPTlRST0xVTkFWQUlMOwoKCWlmICghZnJlcSkgZnJlcSA9IFRoaXMtPndmeC5uU2FtcGxlc1BlclNlYzsKCglpZiAoKGZyZXEgPCBEU0JGUkVRVUVOQ1lfTUlOKSB8fCAoZnJlcSA+IERTQkZSRVFVRU5DWV9NQVgpKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgoJVGhpcy0+ZnJlcSA9IGZyZXE7CglUaGlzLT5mcmVxQWRqdXN0ID0gKGZyZXEgPDwgRFNPVU5EX0ZSRVFTSElGVCkgLyBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWM7CglUaGlzLT5uQXZnQnl0ZXNQZXJTZWMgPSBmcmVxICogVGhpcy0+d2Z4Lm5CbG9ja0FsaWduOwoJRFNPVU5EX1JlY2FsY0Zvcm1hdChUaGlzKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1BsYXkoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIHJlc2VydmVkMSxEV09SRCByZXNlcnZlZDIsRFdPUkQgZmxhZ3MKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCUwOGx4LCUwOGx4LCUwOGx4KVxuIiwKCQlUaGlzLHJlc2VydmVkMSxyZXNlcnZlZDIsZmxhZ3MKCSk7CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgoJVGhpcy0+cGxheWZsYWdzID0gZmxhZ3M7CglpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCVRoaXMtPmxlYWRpbiA9IFRSVUU7CgkJVGhpcy0+c3RhcnRwb3MgPSBUaGlzLT5idWZfbWl4cG9zOwoJCVRoaXMtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7Cgl9IGVsc2UgaWYgKFRoaXMtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKQoJCVRoaXMtPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCWlmICghKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgJiYgVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfUGxheShUaGlzLT5od2J1ZiwgMCwgMCwgVGhpcy0+cGxheWZsYWdzKTsKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7Cgl9CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiAqKioqICovCgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TdG9wKExQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApXG4iLFRoaXMpOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCWlmIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKQoJCVRoaXMtPnN0YXRlID0gU1RBVEVfU1RPUFBJTkc7CgllbHNlIGlmIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpICYmIFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1N0b3AoVGhpcy0+aHdidWYpOwoJCVRoaXMtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCX0KCURTT1VORF9DaGVja0V2ZW50KFRoaXMsIDApOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglEV09SRCByZWY7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGQsIHRocmVhZCBpcyAlbHhcbiIsVGhpcywgVGhpcy0+cmVmLCBHZXRDdXJyZW50VGhyZWFkSWQoKSk7CgoJcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJihUaGlzLT5yZWYpKTsKCWlmICghcmVmKSB7CgkJRklYTUUoInRocmVhZC1zYWZldHkgYWxlcnQhIEFkZFJlZi1pbmcgd2l0aCBhIHplcm8gcmVmY291bnQhXG4iKTsKCX0KCXJldHVybiByZWY7Cn0Kc3RhdGljIERXT1JEIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1JlbGVhc2UoTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJaW50CWk7CglEV09SRCByZWY7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGQsIHRocmVhZCBpcyAlbHhcbiIsVGhpcywgVGhpcy0+cmVmLCBHZXRDdXJyZW50VGhyZWFkSWQoKSk7CgoJcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJihUaGlzLT5yZWYpKTsKCWlmIChyZWYpIHJldHVybiByZWY7CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5kc291bmQtPmxvY2spKTsKCWZvciAoaT0wO2k8VGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycztpKyspCgkJaWYgKFRoaXMtPmRzb3VuZC0+YnVmZmVyc1tpXSA9PSBUaGlzKQoJCQlicmVhazsKCglpZiAoaSA8IFRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnMpIHsKCQkvKiBQdXQgdGhlIGxhc3QgYnVmZmVyIG9mIHRoZSBsaXN0IGluIHRoZSAobm93IGVtcHR5KSBwb3NpdGlvbiAqLwoJCVRoaXMtPmRzb3VuZC0+YnVmZmVyc1tpXSA9IFRoaXMtPmRzb3VuZC0+YnVmZmVyc1tUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzIC0gMV07CgkJVGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycy0tOwoJCVRoaXMtPmRzb3VuZC0+YnVmZmVycyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5kc291bmQtPmJ1ZmZlcnMsc2l6ZW9mKExQRElSRUNUU09VTkRCVUZGRVIpKlRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnMpOwoJCVRSQUNFKCJidWZmZXIgY291bnQgaXMgbm93ICVkXG4iLCBUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzKTsKCQlJRGlyZWN0U291bmRfUmVsZWFzZSgoTFBESVJFQ1RTT1VORClUaGlzLT5kc291bmQpOwoJfQoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5kc291bmQtPmxvY2spKTsKCglEZWxldGVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCURTT1VORF9QcmltYXJ5Q2xvc2UoVGhpcyk7CglpZiAoVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfUmVsZWFzZShUaGlzLT5od2J1Zik7Cgl9CglpZiAoVGhpcy0+ZHMzZGIpCgkJSURpcmVjdFNvdW5kM0RCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VORDNEQlVGRkVSKVRoaXMtPmRzM2RiKTsKCWlmIChUaGlzLT5wYXJlbnQpCgkJLyogdGhpcyBpcyBhIGR1cGxpY2F0ZSBidWZmZXIgKi8KCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5wYXJlbnQpOwoJZWxzZQoJCS8qIHRoaXMgaXMgYSB0b3BsZXZlbCBidWZmZXIgKi8KCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+YnVmZmVyKTsKCglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkKCWlmIChUaGlzID09IHByaW1hcnlidWYpCgkJcHJpbWFyeWJ1ZiA9IE5VTEw7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfQ2FsY1BsYXlQb3NpdGlvbihJRGlyZWN0U291bmRCdWZmZXJJbXBsICpUaGlzLAoJCQkJICAgICBEV09SRCBzdGF0ZSwgRFdPUkQgcHBsYXksIERXT1JEIHB3cml0ZSwgRFdPUkQgcG1peCwgRFdPUkQgYm1peCkKewoJRFdPUkQgYnBsYXk7CgoJVFJBQ0UoInByaW1hcnkgcGxheXBvcz0lbGQsIG1peHBvcz0lbGRcbiIsIHBwbGF5LCBwbWl4KTsKCVRSQUNFKCJ0aGlzIG1peHBvcz0lbGRcbiIsIGJtaXgpOwoKCS8qIHRoZSBhY3R1YWwgcHJpbWFyeSBwbGF5IHBvc2l0aW9uIChwcGxheSkgaXMgYWx3YXlzIGJlaGluZCBsYXN0IG1peGVkIChwbWl4KSwKCSAqIHVubGVzcyB0aGUgY29tcHV0ZXIgaXMgdG9vIHNsb3cgb3Igc29tZXRoaW5nICovCgkvKiB3ZSBuZWVkIHRvIGtub3cgaG93IGZhciBhd2F5IHdlIGFyZSBmcm9tIHRoZXJlICovCglpZiAocG1peCA9PSBwcGxheSkgewoJCWlmICgoc3RhdGUgPT0gU1RBVEVfUExBWUlORykgfHwgKHN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSkgewoJCQkvKiB3b3csIHRoZSBzb2Z0d2FyZSBtaXhlciBpcyByZWFsbHkgZG9pbmcgd2VsbCwKCQkJICogc2VlbXMgdGhlIGVudGlyZSBwcmltYXJ5IGJ1ZmZlciBpcyBmaWxsZWQhICovCgkJCXBtaXggKz0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJCX0KCQkvKiBlbHNlOiB0aGUgcHJpbWFyeSBidWZmZXIgaXMgbm90IHBsYXlpbmcsIHNvIHByb2JhYmx5IGVtcHR5ICovCgl9CglpZiAocG1peCA8IHBwbGF5KSBwbWl4ICs9IHByaW1hcnlidWYtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJcG1peCAtPSBwcGxheTsKCS8qIGRldGVjdCBidWZmZXIgdW5kZXJydW4gKi8KCWlmIChwd3JpdGUgPCBwcGxheSkgcHdyaXRlICs9IHByaW1hcnlidWYtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJcHdyaXRlIC09IHBwbGF5OwoJaWYgKHBtaXggPiAoRFNfU05EX1FVRVVFICogcHJpbWFyeWJ1Zi0+ZHNvdW5kLT5mcmFnbGVuICsgcHdyaXRlICsgcHJpbWFyeWJ1Zi0+d3JpdGVsZWFkKSkgewoJCVdBUk4oImRldGVjdGVkIGFuIHVuZGVycnVuOiBwcmltYXJ5IHF1ZXVlIHdhcyAlbGRcbiIscG1peCk7CgkJcG1peCA9IDA7Cgl9CgkvKiBkaXZpZGUgdGhlIG9mZnNldCBieSBpdHMgc2FtcGxlIHNpemUgKi8KCXBtaXggLz0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoJVFJBQ0UoInByaW1hcnkgYmFjay1zYW1wbGVzPSVsZFxuIixwbWl4KTsKCS8qIGFkanVzdCBmb3Igb3VyIGZyZXF1ZW5jeSAqLwoJcG1peCA9IChwbWl4ICogVGhpcy0+ZnJlcUFkanVzdCkgPj4gRFNPVU5EX0ZSRVFTSElGVDsKCS8qIG11bHRpcGx5IGJ5IG91ciBvd24gc2FtcGxlIHNpemUgKi8KCXBtaXggKj0gVGhpcy0+d2Z4Lm5CbG9ja0FsaWduOwoJVFJBQ0UoInRoaXMgYmFjay1vZmZzZXQ9JWxkXG4iLCBwbWl4KTsKCS8qIHN1YnRyYWN0IGZyb20gb3VyIGxhc3QgbWl4ZWQgcG9zaXRpb24gKi8KCWJwbGF5ID0gYm1peDsKCXdoaWxlIChicGxheSA8IHBtaXgpIGJwbGF5ICs9IFRoaXMtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJYnBsYXkgLT0gcG1peDsKCWlmIChUaGlzLT5sZWFkaW4gJiYgKChicGxheSA8IFRoaXMtPnN0YXJ0cG9zKSB8fCAoYnBsYXkgPiBibWl4KSkpIHsKCQkvKiBzZWVtcyB3ZSBoYXZlbid0IHN0YXJ0ZWQgcGxheWluZyB5ZXQgKi8KCQlUUkFDRSgidGhpcyBzdGlsbCBpbiBsZWFkLWluIHBoYXNlXG4iKTsKCQlicGxheSA9IFRoaXMtPnN0YXJ0cG9zOwoJfQoJLyogcmV0dXJuIHRoZSByZXN1bHQgKi8KCXJldHVybiBicGxheTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIHBsYXlwb3MsTFBEV09SRCB3cml0ZXBvcwopIHsKCUhSRVNVTFQJaHJlczsgCglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwLCVwKVxuIixUaGlzLHBsYXlwb3Msd3JpdGVwb3MpOwoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJaHJlcz1JRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24oVGhpcy0+aHdidWYscGxheXBvcyx3cml0ZXBvcyk7CgkJaWYgKGhyZXMpCgkJICAgIHJldHVybiBocmVzOwoKCX0KCWVsc2UgaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgewoJCWlmIChwbGF5cG9zKSB7CgkJCU1NVElNRSBtdGltZTsKCQkJbXRpbWUud1R5cGUgPSBUSU1FX0JZVEVTOwoJCQl3YXZlT3V0R2V0UG9zaXRpb24oVGhpcy0+ZHNvdW5kLT5od28sICZtdGltZSwgc2l6ZW9mKG10aW1lKSk7CgkJCW10aW1lLnUuY2IgPSBtdGltZS51LmNiICUgVGhpcy0+YnVmbGVuOwoJCQkqcGxheXBvcyA9IG10aW1lLnUuY2I7CgkJfQoJCWlmICh3cml0ZXBvcykgewoJCQkvKiB0aGUgd3JpdGVwb3Mgc2hvdWxkIG9ubHkgYmUgdXNlZCBieSBhcHBzIHdpdGggV1JJVEVQUklNQVJZIHByaW9yaXR5LAoJCQkgKiBpbiB3aGljaCBjYXNlIG91ciBzb2Z0d2FyZSBtaXhlciBpcyBkaXNhYmxlZCBhbnl3YXkgKi8KCQkJKndyaXRlcG9zID0gVGhpcy0+cGxheXBvcyArIERTX0hFTF9NQVJHSU4gKiBUaGlzLT5kc291bmQtPmZyYWdsZW47CgkJCXdoaWxlICgqd3JpdGVwb3MgPj0gVGhpcy0+YnVmbGVuKQoJCQkJKndyaXRlcG9zIC09IFRoaXMtPmJ1ZmxlbjsKCQl9Cgl9IGVsc2UgewoJCWlmIChwbGF5cG9zICYmIChUaGlzLT5zdGF0ZSAhPSBTVEFURV9QTEFZSU5HKSkgewoJCQkvKiB3ZSBoYXZlbid0IGJlZW4gbWVyZ2VkIGludG8gdGhlIHByaW1hcnkgYnVmZmVyICh5ZXQpICovCgkJCSpwbGF5cG9zID0gVGhpcy0+YnVmX21peHBvczsKCQl9CgkJZWxzZSBpZiAocGxheXBvcykgewoJCQlEV09SRCBwcGxheSwgcHdyaXRlLCBscGxheSwgc3BsYXksIHBzdGF0ZTsKCQkJLyogbGV0J3MgZ2V0IHRoaXMgZXhhY3Q7IGZpcnN0LCByZWN1cnNpdmVseSBjYWxsIEdldFBvc2l0aW9uIG9uIHRoZSBwcmltYXJ5ICovCgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJCQlpZiAoKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfR0VUQ1VSUkVOVFBPU0lUSU9OMikgfHwgcHJpbWFyeWJ1Zi0+aHdidWYgfHwgIURTX0VNVUxEUklWRVIpIHsKCQkJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKChMUERJUkVDVFNPVU5EQlVGRkVSKXByaW1hcnlidWYsICZwcGxheSwgJnB3cml0ZSk7CgkJCQkvKiBkZXRlY3QgSEVMIG1vZGUgdW5kZXJydW4gKi8KCQkJCXBzdGF0ZSA9IHByaW1hcnlidWYtPnN0YXRlOwoJCQkJaWYgKCEocHJpbWFyeWJ1Zi0+aHdidWYgfHwgcHJpbWFyeWJ1Zi0+ZHNvdW5kLT5wd3F1ZXVlKSkgewoJCQkJCVRSQUNFKCJkZXRlY3RlZCBhbiB1bmRlcnJ1blxuIik7CgkJCQkJLyogcHBsYXkgPSA/ICovCgkJCQkJaWYgKHBzdGF0ZSA9PSBTVEFURV9QTEFZSU5HKQoJCQkJCQlwc3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJCQllbHNlIGlmIChwc3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpCgkJCQkJCXBzdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCQl9CgkJCQkvKiBnZXQgZGF0YSBmb3Igb3Vyc2VsdmVzIHdoaWxlIHdlIHN0aWxsIGhhdmUgdGhlIGxvY2sgKi8KCQkJCXBzdGF0ZSAmPSBUaGlzLT5zdGF0ZTsKCQkJCWxwbGF5ID0gVGhpcy0+cHJpbWFyeV9taXhwb3M7CgkJCQlzcGxheSA9IFRoaXMtPmJ1Zl9taXhwb3M7CgkJCQkvKiBjYWxjdWxhdGUgcGxheSBwb3NpdGlvbiB1c2luZyB0aGlzICovCgkJCQkqcGxheXBvcyA9IERTT1VORF9DYWxjUGxheVBvc2l0aW9uKFRoaXMsIHBzdGF0ZSwgcHBsYXksIHB3cml0ZSwgbHBsYXksIHNwbGF5KTsKCQkJfSBlbHNlIHsKCQkJCS8qICh1bmxlc3MgdGhlIGFwcCBpc24ndCB1c2luZyBHRVRDVVJSRU5UUE9TSVRJT04yKSAqLwoJCQkJLyogZG9uJ3Qga25vdyBleGFjdGx5IGhvdyB0aGlzIHNob3VsZCBiZSBoYW5kbGVkLi4uCgkJCQkgKiB0aGUgZG9jcyBzYXlzIHRoYXQgcGxheSBjdXJzb3IgaXMgcmVwb3J0ZWQgYXMgZGlyZWN0bHkKCQkJCSAqIGJlaGluZCB3cml0ZSBjdXJzb3IsIGhtbS4uLiAqLwoJCQkJKnBsYXlwb3MgPSBUaGlzLT5wbGF5cG9zOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJCX0KCQlpZiAod3JpdGVwb3MpICp3cml0ZXBvcyA9IFRoaXMtPmJ1Zl9taXhwb3M7Cgl9CglpZiAod3JpdGVwb3MpIHsKCQlpZiAoVGhpcy0+c3RhdGUgIT0gU1RBVEVfU1RPUFBFRCkKCQkJLyogYXBwbHkgdGhlIGRvY3VtZW50ZWQgMTBtcyBsZWFkIHRvIHdyaXRlcG9zICovCgkJCSp3cml0ZXBvcyArPSBUaGlzLT53cml0ZWxlYWQ7CgkJd2hpbGUgKCp3cml0ZXBvcyA+PSBUaGlzLT5idWZsZW4pICp3cml0ZXBvcyAtPSBUaGlzLT5idWZsZW47Cgl9CglUUkFDRSgicGxheXBvcyA9ICVsZCwgd3JpdGVwb3MgPSAlbGQgKCVwLCB0aW1lPSVsZClcbiIsIHBsYXlwb3M/KnBsYXlwb3M6MCwgd3JpdGVwb3M/KndyaXRlcG9zOjAsIFRoaXMsIEdldFRpY2tDb3VudCgpKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0U3RhdHVzKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIHN0YXR1cwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXApLCB0aHJlYWQgaXMgJWx4XG4iLFRoaXMsc3RhdHVzLEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKCglpZiAoc3RhdHVzID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqc3RhdHVzID0gMDsKCWlmICgoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHx8IChUaGlzLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSkKCQkqc3RhdHVzIHw9IERTQlNUQVRVU19QTEFZSU5HOwoJaWYgKFRoaXMtPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykKCQkqc3RhdHVzIHw9IERTQlNUQVRVU19MT09QSU5HOwoKCVRSQUNFKCJzdGF0dXM9JWx4XG4iLCAqc3RhdHVzKTsKCXJldHVybiBEU19PSzsKfQoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEZvcm1hdCgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBXQVZFRk9STUFURVggbHB3ZixEV09SRCB3ZnNpemUsTFBEV09SRCB3ZndyaXR0ZW4KKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwLCVsZCwlcClcbiIsVGhpcyxscHdmLHdmc2l6ZSx3ZndyaXR0ZW4pOwoKCWlmICh3ZnNpemU+c2l6ZW9mKFRoaXMtPndmeCkpCgkJd2ZzaXplID0gc2l6ZW9mKFRoaXMtPndmeCk7CglpZiAobHB3ZikgewkvKiBOVUxMIGlzIHZhbGlkICovCgkJbWVtY3B5KGxwd2YsJihUaGlzLT53ZngpLHdmc2l6ZSk7CgkJaWYgKHdmd3JpdHRlbikKCQkJKndmd3JpdHRlbiA9IHdmc2l6ZTsKCX0gZWxzZQoJCWlmICh3ZndyaXR0ZW4pCgkJCSp3ZndyaXR0ZW4gPSBzaXplb2YoVGhpcy0+d2Z4KTsKCQllbHNlCgkJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Mb2NrKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxEV09SRCB3cml0ZWN1cnNvcixEV09SRCB3cml0ZWJ5dGVzLExQVk9JRCBscGxwYXVkaW9wdHIxLExQRFdPUkQgYXVkaW9ieXRlczEsTFBWT0lEIGxwbHBhdWRpb3B0cjIsTFBEV09SRCBhdWRpb2J5dGVzMixEV09SRCBmbGFncwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCURXT1JEIGNhcGY7CgoJVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVwLCVwLCVwLDB4JTA4bHgpXG4iLAoJCVRoaXMsCgkJd3JpdGVjdXJzb3IsCgkJd3JpdGVieXRlcywKCQlscGxwYXVkaW9wdHIxLAoJCWF1ZGlvYnl0ZXMxLAoJCWxwbHBhdWRpb3B0cjIsCgkJYXVkaW9ieXRlczIsCgkJZmxhZ3MKCSk7CgoJaWYgKGZsYWdzICYgRFNCTE9DS19GUk9NV1JJVEVDVVJTT1IpIHsKCQlEV09SRCB3cml0ZXBvczsKCQkvKiBHZXRDdXJyZW50UG9zaXRpb24gZG9lcyB0b28gbXVjaCBtYWdpYyB0byBkdXBsaWNhdGUgaGVyZSAqLwoJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKGlmYWNlLCBOVUxMLCAmd3JpdGVwb3MpOwoJCXdyaXRlY3Vyc29yICs9IHdyaXRlcG9zOwoJfQoJaWYgKGZsYWdzICYgRFNCTE9DS19FTlRJUkVCVUZGRVIpCgkJd3JpdGVieXRlcyA9IFRoaXMtPmJ1ZmxlbjsKCWlmICh3cml0ZWJ5dGVzID4gVGhpcy0+YnVmbGVuKQoJCXdyaXRlYnl0ZXMgPSBUaGlzLT5idWZsZW47CgoJYXNzZXJ0KGF1ZGlvYnl0ZXMxIT1hdWRpb2J5dGVzMik7Cglhc3NlcnQobHBscGF1ZGlvcHRyMSE9bHBscGF1ZGlvcHRyMik7CgoJaWYgKCh3cml0ZWJ5dGVzID09IFRoaXMtPmJ1ZmxlbikgJiYKCSAgICAoKFRoaXMtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fAoJICAgICAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykpKQoJCS8qIHNvbWUgZ2FtZXMsIGxpa2UgSGFsZi1MaWZlLCB0cnkgdG8gYmUgY2xldmVyIChub3QpIGFuZAoJCSAqIGtlZXAgb25lIHNlY29uZGFyeSBidWZmZXIsIGFuZCBtaXggc291bmRzIGludG8gaXQgaXRzZWxmLAoJCSAqIGxvY2tpbmcgdGhlIGVudGlyZSBidWZmZXIgZXZlcnkgdGltZS4uLiBzbyB3ZSBjYW4ganVzdCBmb3JnZXQKCQkgKiBhYm91dCB0cmFja2luZyB0aGUgbGFzdC13cml0dGVuLXRvLXBvc2l0aW9uLi4uICovCgkJVGhpcy0+cHJvYmFibHlfdmFsaWRfdG8gPSAoRFdPUkQpLTE7CgllbHNlCgkJVGhpcy0+cHJvYmFibHlfdmFsaWRfdG8gPSB3cml0ZWN1cnNvcjsKCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCWNhcGYgPSBEU0RERVNDX0RPTlRORUVEUFJJTUFSWUxPQ0s7CgllbHNlCgkJY2FwZiA9IERTRERFU0NfRE9OVE5FRURTRUNPTkRBUllMT0NLOwoJaWYgKCEoVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBjYXBmKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9Mb2NrKFRoaXMtPmh3YnVmLAoJCQkJICAgICBscGxwYXVkaW9wdHIxLCBhdWRpb2J5dGVzMSwKCQkJCSAgICAgbHBscGF1ZGlvcHRyMiwgYXVkaW9ieXRlczIsCgkJCQkgICAgIHdyaXRlY3Vyc29yLCB3cml0ZWJ5dGVzLAoJCQkJICAgICAwKTsKCX0gZWxzZQoJaWYgKHdyaXRlY3Vyc29yK3dyaXRlYnl0ZXMgPD0gVGhpcy0+YnVmbGVuKSB7CgkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjEgPSBUaGlzLT5idWZmZXIrd3JpdGVjdXJzb3I7CgkJKmF1ZGlvYnl0ZXMxID0gd3JpdGVieXRlczsKCQlpZiAobHBscGF1ZGlvcHRyMikKCQkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjIgPSBOVUxMOwoJCWlmIChhdWRpb2J5dGVzMikKCQkJKmF1ZGlvYnl0ZXMyID0gMDsKCQlUUkFDRSgiLT4lbGQuMFxuIix3cml0ZWJ5dGVzKTsKCX0gZWxzZSB7CgkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjEgPSBUaGlzLT5idWZmZXIrd3JpdGVjdXJzb3I7CgkJKmF1ZGlvYnl0ZXMxID0gVGhpcy0+YnVmbGVuLXdyaXRlY3Vyc29yOwoJCWlmIChscGxwYXVkaW9wdHIyKQoJCQkqKExQQllURSopbHBscGF1ZGlvcHRyMiA9IFRoaXMtPmJ1ZmZlcjsKCQlpZiAoYXVkaW9ieXRlczIpCgkJCSphdWRpb2J5dGVzMiA9IHdyaXRlYnl0ZXMtKFRoaXMtPmJ1Zmxlbi13cml0ZWN1cnNvcik7CgkJVFJBQ0UoIi0+JWxkLiVsZFxuIiwqYXVkaW9ieXRlczEsYXVkaW9ieXRlczI/KmF1ZGlvYnl0ZXMyOjApOwoJfQoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRDdXJyZW50UG9zaXRpb24oCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIG5ld3BvcwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJWxkKVxuIixUaGlzLG5ld3Bvcyk7CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgoJVGhpcy0+YnVmX21peHBvcyA9IG5ld3BvczsKCWlmIChUaGlzLT5od2J1ZikKCQlJRHNEcml2ZXJCdWZmZXJfU2V0UG9zaXRpb24oVGhpcy0+aHdidWYsIFRoaXMtPmJ1Zl9taXhwb3MpOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0UGFuKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMT05HIHBhbgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyxwYW4pOwoKCWlmICgocGFuID4gRFNCUEFOX1JJR0hUKSB8fCAocGFuIDwgRFNCUEFOX0xFRlQpKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogWW91IGNhbm5vdCBzZXQgdGhlIHBhbiBvZiB0aGUgcHJpbWFyeSBidWZmZXIgKi8KCS8qIGFuZCB5b3UgY2Fubm90IHVzZSBib3RoIHBhbiBhbmQgM0QgY29udHJvbHMgKi8KCWlmICghKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpIHx8CgkgICAgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikpCgkJcmV0dXJuIERTRVJSX0NPTlRST0xVTkFWQUlMOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPnZvbHBhbi5sUGFuID0gcGFuOwoKCURTT1VORF9SZWNhbGNWb2xQYW4oJihUaGlzLT52b2xwYW4pKTsKCglpZiAoVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfU2V0Vm9sdW1lUGFuKFRoaXMtPmh3YnVmLCAmKFRoaXMtPnZvbHBhbikpOwoJfQoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0UGFuKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUExPTkcgcGFuCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcClcbiIsVGhpcyxwYW4pOwoKCWlmIChwYW4gPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCSpwYW4gPSBUaGlzLT52b2xwYW4ubFBhbjsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1VubG9jaygKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBWT0lEIHAxLERXT1JEIHgxLExQVk9JRCBwMixEV09SRCB4MgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCURXT1JEIGNhcGYsIHByb2JhYmx5X3ZhbGlkX3RvOwoKCVRSQUNFKCIoJXAsJXAsJWxkLCVwLCVsZCk6c3R1YlxuIiwgVGhpcyxwMSx4MSxwMix4Mik7CgojaWYgMAoJLyogUHJlcHJvY2VzcyAzRCBidWZmZXJzLi4uICovCgoJLyogVGhpcyBpcyBoaWdobHkgZXhwZXJpbWVudGFsIGFuZCBsaWFibGUgdG8gYnJlYWsgdGhpbmdzICovCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpCgkJRFNPVU5EX0NyZWF0ZTNEQnVmZmVyKFRoaXMpOwojZW5kaWYKCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCWNhcGYgPSBEU0RERVNDX0RPTlRORUVEUFJJTUFSWUxPQ0s7CgllbHNlCgkJY2FwZiA9IERTRERFU0NfRE9OVE5FRURTRUNPTkRBUllMT0NLOwoJaWYgKCEoVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBjYXBmKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9VbmxvY2soVGhpcy0+aHdidWYsIHAxLCB4MSwgcDIsIHgyKTsKCX0KCglpZiAocDIpIHByb2JhYmx5X3ZhbGlkX3RvID0gKCgoTFBCWVRFKXAyKS1UaGlzLT5idWZmZXIpICsgeDI7CgllbHNlIHByb2JhYmx5X3ZhbGlkX3RvID0gKCgoTFBCWVRFKXAxKS1UaGlzLT5idWZmZXIpICsgeDE7Cgl3aGlsZSAocHJvYmFibHlfdmFsaWRfdG8gPj0gVGhpcy0+YnVmbGVuKQoJCXByb2JhYmx5X3ZhbGlkX3RvIC09IFRoaXMtPmJ1ZmxlbjsKCWlmICgocHJvYmFibHlfdmFsaWRfdG8gPT0gMCkgJiYgKCh4MSt4MikgPT0gVGhpcy0+YnVmbGVuKSAmJgoJICAgICgoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHx8CgkgICAgIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSkpCgkJLyogc2VlIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfTG9jayAqLwoJCXByb2JhYmx5X3ZhbGlkX3RvID0gKERXT1JEKS0xOwoJVGhpcy0+cHJvYmFibHlfdmFsaWRfdG8gPSBwcm9iYWJseV92YWxpZF90bzsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1Jlc3RvcmUoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRklYTUUoIiglcCk6c3R1YlxuIixUaGlzKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0RnJlcXVlbmN5KAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIGZyZXEKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwKVxuIixUaGlzLGZyZXEpOwoKCWlmIChmcmVxID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqZnJlcSA9IFRoaXMtPmZyZXE7CglUUkFDRSgiLT4gJWxkXG4iLCAqZnJlcSk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Jbml0aWFsaXplKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERJUkVDVFNPVU5EIGRzb3VuZCxMUERTQlVGRkVSREVTQyBkYnNkCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRklYTUUoIiglcCwlcCwlcCk6c3R1YlxuIixUaGlzLGRzb3VuZCxkYnNkKTsKCURQUklOVEYoIlJlLUluaXQhISFcbiIpOwoJcmV0dXJuIERTRVJSX0FMUkVBRFlJTklUSUFMSVpFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q2FwcygKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBEU0JDQVBTIGNhcHMKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CiAgCVRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsY2Fwcyk7CiAgCglpZiAoY2FwcyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogSSB0aGluayB3ZSBzaG91bGQgY2hlY2sgdGhpcyB2YWx1ZSwgbm90IHNldCBpdC4gU2VlICovCgkvKiBJbnNpZGUgRGlyZWN0WCwgcDIxNS4gVGhhdCBzaG91bGQgYXBwbHkgaGVyZSwgdG9vLiAqLwoJY2Fwcy0+ZHdTaXplID0gc2l6ZW9mKCpjYXBzKTsKCgljYXBzLT5kd0ZsYWdzID0gVGhpcy0+ZHNiZC5kd0ZsYWdzOwoJaWYgKFRoaXMtPmh3YnVmKSBjYXBzLT5kd0ZsYWdzIHw9IERTQkNBUFNfTE9DSEFSRFdBUkU7CgllbHNlIGNhcHMtPmR3RmxhZ3MgfD0gRFNCQ0FQU19MT0NTT0ZUV0FSRTsKCgljYXBzLT5kd0J1ZmZlckJ5dGVzID0gVGhpcy0+ZHNiZC5kd0J1ZmZlckJ5dGVzOwoKCS8qIFRoaXMgdmFsdWUgcmVwcmVzZW50cyB0aGUgc3BlZWQgb2YgdGhlICJ1bmxvY2siIGNvbW1hbmQuCgkgICBBcyB1bmxvY2sgaXMgcXVpdGUgZmFzdCAoaXQgZG9lcyBub3QgZG8gYW55dGhpbmcpLCBJIHB1dAoJICAgNDA5NiBrby9zID0gNCBNbyAvIHMgKi8KCS8qIEZJWE1FOiBod2J1ZiBzcGVlZCAqLwoJY2Fwcy0+ZHdVbmxvY2tUcmFuc2ZlclJhdGUgPSA0MDk2OwoJY2Fwcy0+ZHdQbGF5Q3B1T3ZlcmhlYWQgPSAwOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZE5vdGlmeSwgcmlpZCApICkgewoJCUlEaXJlY3RTb3VuZE5vdGlmeUltcGwJKmRzbjsKCgkJZHNuID0gKElEaXJlY3RTb3VuZE5vdGlmeUltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCpkc24pKTsKCQlkc24tPnJlZiA9IDE7CgkJZHNuLT5kc2IgPSBUaGlzOwoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJCUlDT01fVlRCTChkc24pID0gJmRzbnZ0OwoJCSpwcG9iaiA9IChMUFZPSUQpZHNuOwoJCXJldHVybiBTX09LOwoJfQoKI2lmIFVTRV9EU09VTkQzRAoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQzREJ1ZmZlciwgcmlpZCApICkgewogICAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsICAgICAgICAqZHMzZGI7CgoJCSpwcG9iaiA9IFRoaXMtPmRzM2RiOwoJCWlmICgqcHBvYmopIHsKCQkJSURpcmVjdFNvdW5kM0RCdWZmZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RCVUZGRVIpVGhpcy0+ZHMzZGIpOwoJCQlyZXR1cm4gU19PSzsKCQl9CgogICAgICAgICAgICAgICAgZHMzZGIgPSAoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKICAgICAgICAgICAgICAgICAgICAgICAgMCxzaXplb2YoKmRzM2RiKSk7CiAgICAgICAgICAgICAgICBkczNkYi0+cmVmID0gMTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kc2IgPSBUaGlzOwogICAgICAgICAgICAgICAgSUNPTV9WVEJMKGRzM2RiKSA9ICZkczNkYnZ0OwoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJmRzM2RiLT5sb2NrKTsKCgkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZihpZmFjZSk7CgogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3U2l6ZSA9IHNpemVvZihEUzNEQlVGRkVSKTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52UG9zaXRpb24udTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52UG9zaXRpb24udTIueSA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52UG9zaXRpb24udTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52VmVsb2NpdHkudTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52VmVsb2NpdHkudTIueSA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52VmVsb2NpdHkudTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd0luc2lkZUNvbmVBbmdsZSA9IERTM0RfREVGQVVMVENPTkVBTkdMRTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd091dHNpZGVDb25lQW5nbGUgPSBEUzNEX0RFRkFVTFRDT05FQU5HTEU7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi51MS54ID0gMC4wOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLnZDb25lT3JpZW50YXRpb24udTIueSA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52Q29uZU9yaWVudGF0aW9uLnUzLnogPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIubENvbmVPdXRzaWRlVm9sdW1lID0gRFMzRF9ERUZBVUxUQ09ORU9VVFNJREVWT0xVTUU7ICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5mbE1pbkRpc3RhbmNlID0gRFMzRF9ERUZBVUxUTUlORElTVEFOQ0U7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZmxNYXhEaXN0YW5jZSA9IERTM0RfREVGQVVMVE1BWERJU1RBTkNFOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX05PUk1BTDsKICAgICAgICAgICAgICAgIGRzM2RiLT5idWZsZW4gPSAoVGhpcy0+YnVmbGVuICogcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduKSAvCiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKICAgICAgICAgICAgICAgIGRzM2RiLT5idWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHMzZGItPmJ1Zmxlbik7CiAgICAgICAgICAgICAgICBpZiAoZHMzZGItPmJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRzM2RiLT5idWZsZW4gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZHdNb2RlID0gRFMzRE1PREVfRElTQUJMRTsKICAgICAgICAgICAgICAgIH0KCgkJZHMzZGItPmlrcyA9IChJS3NQcm9wZXJ0eVNldEltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCooZHMzZGItPmlrcykpKTsKCQlkczNkYi0+aWtzLT5yZWYgPSAxOwoJCWRzM2RiLT5pa3MtPmRzM2RiID0gZHMzZGI7CgkJSUNPTV9WVEJMKGRzM2RiLT5pa3MpID0gJmlrc3Z0OwoKCQlyZXR1cm4gU19PSzsKCX0KI2Vsc2UKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kM0RCdWZmZXIsIHJpaWQgKSApIHsKCQlGSVhNRSgiJXM6IEkga25vdyBhYm91dCB0aGlzIEdVSUQsIGJ1dCBkb24ndCBzdXBwb3J0IGl0IHlldFxuIiwKCQkgICAgICBkZWJ1Z3N0cl9ndWlkKCByaWlkICkpOwoJCSpwcG9iaiA9IE5VTEw7CgkJcmV0dXJuIEVfRkFJTDsKCX0KI2VuZGlmCgogICAgICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kM0RMaXN0ZW5lciwgcmlpZCApICkgewoJCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsKiBkc2w7CgoJCWlmIChUaGlzLT5kc291bmQtPmxpc3RlbmVyKSB7CgkJCSpwcG9iaiA9IFRoaXMtPmRzb3VuZC0+bGlzdGVuZXI7CiAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3RTb3VuZDNETGlzdGVuZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RMSVNURU5FUilUaGlzLT5kc291bmQtPmxpc3RlbmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERTX09LOwoJCX0KCgkJZHNsID0gKElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZigqZHNsKSk7CgkJZHNsLT5yZWYgPSAxOwoJCUlDT01fVlRCTChkc2wpID0gJmRzM2RsdnQ7CgkJKnBwb2JqID0gKExQVk9JRClkc2w7CgogICAgICAgICAgICAgICAgZHNsLT5kczNkbC5kd1NpemUgPSBzaXplb2YoRFMzRExJU1RFTkVSKTsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlBvc2l0aW9uLnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZQb3NpdGlvbi51Mi55ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52UG9zaXRpb24udTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlZlbG9jaXR5LnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZWZWxvY2l0eS51Mi55ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52VmVsb2NpdHkudTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudEZyb250LnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRGcm9udC51Mi55ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50RnJvbnQudTMueiA9IDEuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudFRvcC51MS54ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50VG9wLnUyLnkgPSAxLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRUb3AudTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwuZmxEaXN0YW5jZUZhY3RvciA9IERTM0RfREVGQVVMVERJU1RBTkNFRkFDVE9SOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC5mbFJvbGxvZmZGYWN0b3IgPSBEUzNEX0RFRkFVTFRST0xMT0ZGRkFDVE9SOwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZkc2wtPmxvY2spOwoKCQlkc2wtPmRzYiA9IFRoaXM7CgkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZihpZmFjZSk7CgoJCVRoaXMtPmRzb3VuZC0+bGlzdGVuZXIgPSBkc2w7CgkJSURpcmVjdFNvdW5kM0RMaXN0ZW5lcl9BZGRSZWYoKExQRElSRUNUU09VTkQzRExJU1RFTkVSKWRzbCk7CgoJCXJldHVybiBTX09LOwoJfQoKCUZJWE1FKCAiVW5rbm93biBHVUlEICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKCByaWlkICkgKTsKCgkqcHBvYmogPSBOVUxMOwoKCXJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRCdWZmZXIpIGRzYnZ0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9BZGRSZWYsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1JlbGVhc2UsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldENhcHMsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Rm9ybWF0LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRWb2x1bWUsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFBhbiwKICAgICAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEZyZXF1ZW5jeSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0U3RhdHVzLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Jbml0aWFsaXplLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Mb2NrLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9QbGF5LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRDdXJyZW50UG9zaXRpb24sCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZvcm1hdCwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Vm9sdW1lLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRQYW4sCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZyZXF1ZW5jeSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU3RvcCwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfVW5sb2NrLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9SZXN0b3JlCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSURpcmVjdFNvdW5kCiAqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfU2V0Q29vcGVyYXRpdmVMZXZlbCgKCUxQRElSRUNUU09VTkQgaWZhY2UsSFdORCBod25kLERXT1JEIGxldmVsCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJTA4bHgsJWxkKTpzdHViXG4iLFRoaXMsKERXT1JEKWh3bmQsbGV2ZWwpOwoKCVRoaXMtPnByaW9sZXZlbCA9IGxldmVsOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfQ3JlYXRlU291bmRCdWZmZXIoCglMUERJUkVDVFNPVU5EIGlmYWNlLExQRFNCVUZGRVJERVNDIGRzYmQsTFBMUERJUkVDVFNPVU5EQlVGRkVSIHBwZHNiLExQVU5LTk9XTiBscHVuawopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKiBpcHBkc2I9KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKilwcGRzYjsKCUxQV0FWRUZPUk1BVEVYCXdmZXg7CglIUkVTVUxUIGVyciA9IERTX09LOwoKCVRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLFRoaXMsZHNiZCxpcHBkc2IsbHB1bmspOwoJCglpZiAoKFRoaXMgPT0gTlVMTCkgfHwgKGRzYmQgPT0gTlVMTCkgfHwgKGlwcGRzYiA9PSBOVUxMKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJCglpZiAoVFJBQ0VfT04oZHNvdW5kKSkgewoJCVRSQUNFKCIoc3RydWN0c2l6ZT0lbGQpXG4iLGRzYmQtPmR3U2l6ZSk7CgkJVFJBQ0UoIihmbGFncz0weCUwOGx4OlxuIixkc2JkLT5kd0ZsYWdzKTsKCQlfZHVtcF9EU0JDQVBTKGRzYmQtPmR3RmxhZ3MpOwoJCURQUklOVEYoIilcbiIpOwoJCVRSQUNFKCIoYnVmZmVyYnl0ZXM9JWxkKVxuIixkc2JkLT5kd0J1ZmZlckJ5dGVzKTsKCQlUUkFDRSgiKGxwd2Z4Rm9ybWF0PSVwKVxuIixkc2JkLT5scHdmeEZvcm1hdCk7Cgl9CgoJd2ZleCA9IGRzYmQtPmxwd2Z4Rm9ybWF0OwoKCWlmICh3ZmV4KQoJCVRSQUNFKCIoZm9ybWF0dGFnPTB4JTA0eCxjaGFucz0lZCxzYW1wbGVyYXRlPSVsZCwiCgkJICAgImJ5dGVzcGVyc2VjPSVsZCxibG9ja2FsaWduPSVkLGJpdHNwZXJzYW1wPSVkLGNiU2l6ZT0lZClcbiIsCgkJICAgd2ZleC0+d0Zvcm1hdFRhZywgd2ZleC0+bkNoYW5uZWxzLCB3ZmV4LT5uU2FtcGxlc1BlclNlYywKCQkgICB3ZmV4LT5uQXZnQnl0ZXNQZXJTZWMsIHdmZXgtPm5CbG9ja0FsaWduLCAKCQkgICB3ZmV4LT53Qml0c1BlclNhbXBsZSwgd2ZleC0+Y2JTaXplKTsKCglpZiAoZHNiZC0+ZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgewoJCWlmIChwcmltYXJ5YnVmKSB7CgkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoKExQRElSRUNUU09VTkRCVUZGRVIpcHJpbWFyeWJ1Zik7CgkJCSppcHBkc2IgPSBwcmltYXJ5YnVmOwoJCQlwcmltYXJ5YnVmLT5kc2JkLmR3RmxhZ3MgPSBkc2JkLT5kd0ZsYWdzOwoJCQlyZXR1cm4gRFNfT0s7CgkJfSAvKiBFbHNlIGNyZWF0ZSBwcmltYXJ5IGJ1ZmZlciAqLwoJfQoKCSppcHBkc2IgPSAoSURpcmVjdFNvdW5kQnVmZmVySW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCkpOwoJaWYgKCppcHBkc2IgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CglJQ09NX1ZUQkwoKmlwcGRzYikgPSAmZHNidnQ7CgkoKmlwcGRzYiktPnJlZiA9IDE7CgkoKmlwcGRzYiktPmRzb3VuZCA9IFRoaXM7CgkoKmlwcGRzYiktPnBhcmVudCA9IE5VTEw7CgkoKmlwcGRzYiktPmJ1ZmZlciA9IE5VTEw7CgoJbWVtY3B5KCYoKCppcHBkc2IpLT5kc2JkKSxkc2JkLHNpemVvZigqZHNiZCkpOwoJaWYgKGRzYmQtPmxwd2Z4Rm9ybWF0KQoJCW1lbWNweSgmKCgqaXBwZHNiKS0+d2Z4KSwgZHNiZC0+bHB3ZnhGb3JtYXQsIHNpemVvZigoKmlwcGRzYiktPndmeCkpOwoKCVRSQUNFKCJDcmVhdGVkIGJ1ZmZlciBhdCAlcFxuIiwgKmlwcGRzYik7CgoJaWYgKGRzYmQtPmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpIHsKCQkoKmlwcGRzYiktPmJ1ZmxlbiA9IGRzb3VuZC0+d2Z4Lm5BdmdCeXRlc1BlclNlYzsKCQkoKmlwcGRzYiktPmZyZXEgPSBkc291bmQtPndmeC5uU2FtcGxlc1BlclNlYzsKCgkJLyogRklYTUU6IHZlcmlmeSB0aGF0IGhhcmR3YXJlIGNhcGFiaWxpdGllcyAoRFNDQVBTX1BSSU1BUlkgZmxhZ3MpIG1hdGNoICovCgoJCWlmIChUaGlzLT5kcml2ZXIpIHsKCQkJZXJyID0gSURzRHJpdmVyX0NyZWF0ZVNvdW5kQnVmZmVyKFRoaXMtPmRyaXZlcix3ZmV4LGRzYmQtPmR3RmxhZ3MsMCwKCQkJCQkJCSAgJigoKmlwcGRzYiktPmJ1ZmxlbiksJigoKmlwcGRzYiktPmJ1ZmZlciksCgkJCQkJCQkgIChMUFZPSUQqKSYoKCppcHBkc2IpLT5od2J1ZikpOwoJCX0KCQlpZiAoZXJyID09IERTX09LKQoJCQllcnIgPSBEU09VTkRfUHJpbWFyeU9wZW4oKmlwcGRzYik7Cgl9IGVsc2UgewoJCURXT1JEIGNhcGYgPSAwOwoJCWludCB1c2VfaHc7CgoJCSgqaXBwZHNiKS0+YnVmbGVuID0gZHNiZC0+ZHdCdWZmZXJCeXRlczsKCQkoKmlwcGRzYiktPmZyZXEgPSBkc2JkLT5scHdmeEZvcm1hdC0+blNhbXBsZXNQZXJTZWM7CgoJCS8qIENoZWNrIG5lY2Vzc2FyeSBoYXJkd2FyZSBtaXhpbmcgY2FwYWJpbGl0aWVzICovCgkJaWYgKHdmZXgtPm5DaGFubmVscz09MikgY2FwZiB8PSBEU0NBUFNfU0VDT05EQVJZU1RFUkVPOwoJCWVsc2UgY2FwZiB8PSBEU0NBUFNfU0VDT05EQVJZTU9OTzsKCQlpZiAod2ZleC0+d0JpdHNQZXJTYW1wbGU9PTE2KSBjYXBmIHw9IERTQ0FQU19TRUNPTkRBUlkxNkJJVDsKCQllbHNlIGNhcGYgfD0gRFNDQVBTX1NFQ09OREFSWThCSVQ7CgkJdXNlX2h3ID0gKFRoaXMtPmRydmNhcHMuZHdGbGFncyAmIGNhcGYpID09IGNhcGY7CgoJCS8qIEZJWE1FOiBjaGVjayBoYXJkd2FyZSBzYW1wbGUgcmF0ZSBtaXhpbmcgY2FwYWJpbGl0aWVzICovCgkJLyogRklYTUU6IGNoZWNrIGFwcCBoaW50cyBmb3Igc29mdHdhcmUvaGFyZHdhcmUgYnVmZmVyIChTVEFUSUMsIExPQ0hBUkRXQVJFLCBldGMpICovCgkJLyogRklYTUU6IGNoZWNrIHdoZXRoZXIgYW55IGhhcmR3YXJlIGJ1ZmZlcnMgYXJlIGxlZnQgKi8KCQkvKiBGSVhNRTogaGFuZGxlIERTREhFQVBfQ1JFQVRFSEVBUCBmb3IgaGFyZHdhcmUgYnVmZmVycyAqLwoKCQkvKiBBbGxvY2F0ZSBzeXN0ZW0gbWVtb3J5IGlmIGFwcGxpY2FibGUgKi8KCQlpZiAoKFRoaXMtPmRydmRlc2MuZHdGbGFncyAmIERTRERFU0NfVVNFU1lTVEVNTUVNT1JZKSB8fCAhdXNlX2h3KSB7CgkJCSgqaXBwZHNiKS0+YnVmZmVyID0gKExQQllURSlIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLCgqaXBwZHNiKS0+YnVmbGVuKTsKCQkJaWYgKCgqaXBwZHNiKS0+YnVmZmVyID09IE5VTEwpCgkJCQllcnIgPSBEU0VSUl9PVVRPRk1FTU9SWTsKCQl9CgoJCS8qIEFsbG9jYXRlIHRoZSBoYXJkd2FyZSBidWZmZXIgKi8KCQlpZiAodXNlX2h3ICYmIChlcnIgPT0gRFNfT0spKSB7CgkJCWVyciA9IElEc0RyaXZlcl9DcmVhdGVTb3VuZEJ1ZmZlcihUaGlzLT5kcml2ZXIsd2ZleCxkc2JkLT5kd0ZsYWdzLDAsCgkJCQkJCQkgICYoKCppcHBkc2IpLT5idWZsZW4pLCYoKCppcHBkc2IpLT5idWZmZXIpLAoJCQkJCQkJICAoTFBWT0lEKikmKCgqaXBwZHNiKS0+aHdidWYpKTsKCQl9Cgl9CgoJaWYgKGVyciAhPSBEU19PSykgewoJCWlmICgoKmlwcGRzYiktPmJ1ZmZlcikKCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCgqaXBwZHNiKS0+YnVmZmVyKTsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKCppcHBkc2IpKTsKCQkqaXBwZHNiID0gTlVMTDsKCQlyZXR1cm4gZXJyOwoJfQoJLyogY2FsY3VsYXRlIGZyYWdtZW50IHNpemUgYW5kIHdyaXRlIGxlYWQgKi8KCURTT1VORF9SZWNhbGNGb3JtYXQoKmlwcGRzYik7CgoJLyogSXQncyBub3QgbmVjZXNzYXJ5IHRvIGluaXRpYWxpemUgdmFsdWVzIHRvIHplcm8gc2luY2UgKi8KCS8qIHdlIGFsbG9jYXRlZCB0aGlzIHN0cnVjdHVyZSB3aXRoIEhFQVBfWkVST19NRU1PUlkuLi4gKi8KCSgqaXBwZHNiKS0+cGxheXBvcyA9IDA7CgkoKmlwcGRzYiktPmJ1Zl9taXhwb3MgPSAwOwoJKCppcHBkc2IpLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CglEU09VTkRfUmVjYWxjVm9sUGFuKCYoKCppcHBkc2IpLT52b2xwYW4pKTsKCglpZiAoIShkc2JkLT5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSkgewoJCSgqaXBwZHNiKS0+ZnJlcUFkanVzdCA9ICgoKmlwcGRzYiktPmZyZXEgPDwgRFNPVU5EX0ZSRVFTSElGVCkgLwoJCQlwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWM7CgkJKCppcHBkc2IpLT5uQXZnQnl0ZXNQZXJTZWMgPSAoKmlwcGRzYiktPmZyZXEgKgoJCQlkc2JkLT5scHdmeEZvcm1hdC0+bkJsb2NrQWxpZ247Cgl9CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiByZWdpc3RlciBidWZmZXIgKi8KCWlmICghKGRzYmQtPmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpKSB7CgkJSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqKm5ld2J1ZmZlcnMgPSAoSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqKUhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5idWZmZXJzLHNpemVvZihJRGlyZWN0U291bmRCdWZmZXJJbXBsKikqKFRoaXMtPm5yb2ZidWZmZXJzKzEpKTsKCQlpZiAobmV3YnVmZmVycykgewoJCQlUaGlzLT5idWZmZXJzID0gbmV3YnVmZmVyczsKCQkJVGhpcy0+YnVmZmVyc1tUaGlzLT5ucm9mYnVmZmVyc10gPSAqaXBwZHNiOwoJCQlUaGlzLT5ucm9mYnVmZmVycysrOwoJCQlUUkFDRSgiYnVmZmVyIGNvdW50IGlzIG5vdyAlZFxuIiwgVGhpcy0+bnJvZmJ1ZmZlcnMpOwoJCX0gZWxzZSB7CgkJCUVSUigib3V0IG9mIG1lbW9yeSBmb3IgYnVmZmVyIGxpc3QhIEN1cnJlbnQgYnVmZmVyIGNvdW50IGlzICVkXG4iLCBUaGlzLT5ucm9mYnVmZmVycyk7CgkJCWVyciA9IERTRVJSX09VVE9GTUVNT1JZOwoJCX0KCX0KCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCUlEaXJlY3RTb3VuZF9BZGRSZWYoaWZhY2UpOwoKCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJigoKmlwcGRzYiktPmxvY2spKTsKCglpZiAoZXJyICE9IERTX09LKSB7CgkJLyogb29wcy4uLiAqLwoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKCpwcGRzYik7CgkJKmlwcGRzYiA9IE5VTEw7CgkJcmV0dXJuIGVycjsKCX0KCQojaWYgVVNFX0RTT1VORDNECglpZiAoZHNiZC0+ZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSB7CgkJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsCSpkczNkYjsKCgkJZHMzZGIgPSAoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKCQkJMCxzaXplb2YoKmRzM2RiKSk7CgkJSUNPTV9WVEJMKGRzM2RiKSA9ICZkczNkYnZ0OwoJCWRzM2RiLT5yZWYgPSAxOwoJCSgqaXBwZHNiKS0+ZHMzZGIgPSBkczNkYjsKCgkJZHMzZGItPmRzYiA9ICgqaXBwZHNiKTsKCQlJRGlyZWN0U291bmRCdWZmZXJJbXBsX0FkZFJlZigoTFBESVJFQ1RTT1VOREJVRkZFUikoKmlwcGRzYikpOwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZkczNkYi0+bG9jayk7CgoJCWRzM2RiLT5kczNkYi5kd1NpemUgPSBzaXplb2YoRFMzREJVRkZFUik7CgkJZHMzZGItPmRzM2RiLnZQb3NpdGlvbi51MS54ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52UG9zaXRpb24udTIueSA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudlBvc2l0aW9uLnUzLnogPSAwLjA7CgkJZHMzZGItPmRzM2RiLnZWZWxvY2l0eS51MS54ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52VmVsb2NpdHkudTIueSA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudlZlbG9jaXR5LnUzLnogPSAwLjA7CgkJZHMzZGItPmRzM2RiLmR3SW5zaWRlQ29uZUFuZ2xlID0gRFMzRF9ERUZBVUxUQ09ORUFOR0xFOwoJCWRzM2RiLT5kczNkYi5kd091dHNpZGVDb25lQW5nbGUgPSBEUzNEX0RFRkFVTFRDT05FQU5HTEU7CgkJZHMzZGItPmRzM2RiLnZDb25lT3JpZW50YXRpb24udTEueCA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi51Mi55ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52Q29uZU9yaWVudGF0aW9uLnUzLnogPSAwLjA7CgkJZHMzZGItPmRzM2RiLmxDb25lT3V0c2lkZVZvbHVtZSA9IERTM0RfREVGQVVMVENPTkVPVVRTSURFVk9MVU1FOwoJCWRzM2RiLT5kczNkYi5mbE1pbkRpc3RhbmNlID0gRFMzRF9ERUZBVUxUTUlORElTVEFOQ0U7CgkJZHMzZGItPmRzM2RiLmZsTWF4RGlzdGFuY2UgPSBEUzNEX0RFRkFVTFRNQVhESVNUQU5DRTsKCQlkczNkYi0+ZHMzZGIuZHdNb2RlID0gRFMzRE1PREVfTk9STUFMOwoJCWRzM2RiLT5idWZsZW4gPSAoKCppcHBkc2IpLT5idWZsZW4gKiBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ24pIC8KCQkJKCppcHBkc2IpLT53ZngubkJsb2NrQWxpZ247CgkJZHMzZGItPmJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkczNkYi0+YnVmbGVuKTsKCQlpZiAoZHMzZGItPmJ1ZmZlciA9PSBOVUxMKSB7CgkJCWRzM2RiLT5idWZsZW4gPSAwOwoJCQlkczNkYi0+ZHMzZGIuZHdNb2RlID0gRFMzRE1PREVfRElTQUJMRTsKCQl9CgkJZHMzZGItPmlrcyA9IChJS3NQcm9wZXJ0eVNldEltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCooZHMzZGItPmlrcykpKTsKCQlkczNkYi0+aWtzLT5yZWYgPSAxOwoJCWRzM2RiLT5pa3MtPmRzM2RiID0gZHMzZGI7CgkJSUNPTV9WVEJMKGRzM2RiLT5pa3MpID0gJmlrc3Z0OwoKCX0KI2VuZGlmCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0R1cGxpY2F0ZVNvdW5kQnVmZmVyKAoJTFBESVJFQ1RTT1VORCBpZmFjZSxMUERJUkVDVFNPVU5EQlVGRkVSIHBkc2IsTFBMUERJUkVDVFNPVU5EQlVGRkVSIHBwZHNiCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbCogaXBkc2I9KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKXBkc2I7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogaXBwZHNiPShJRGlyZWN0U291bmRCdWZmZXJJbXBsKiopcHBkc2I7CglUUkFDRSgiKCVwLCVwLCVwKVxuIixUaGlzLGlwZHNiLGlwcGRzYik7CgoJaWYgKGlwZHNiLT5od2J1ZikgewoJCUZJWE1FKCJuZWVkIHRvIGR1cGxpY2F0ZSBoYXJkd2FyZSBidWZmZXJcbiIpOwoJfQoKCSppcHBkc2IgPSAoSURpcmVjdFNvdW5kQnVmZmVySW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCkpOwoKCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYocGRzYik7CgltZW1jcHkoKmlwcGRzYiwgaXBkc2IsIHNpemVvZihJRGlyZWN0U291bmRCdWZmZXJJbXBsKSk7CgkoKmlwcGRzYiktPnJlZiA9IDE7CgkoKmlwcGRzYiktPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCSgqaXBwZHNiKS0+cGxheXBvcyA9IDA7CgkoKmlwcGRzYiktPmJ1Zl9taXhwb3MgPSAwOwoJKCppcHBkc2IpLT5kc291bmQgPSBUaGlzOwoJKCppcHBkc2IpLT5wYXJlbnQgPSBpcGRzYjsKCW1lbWNweSgmKCgqaXBwZHNiKS0+d2Z4KSwgJihpcGRzYi0+d2Z4KSwgc2l6ZW9mKCgqaXBwZHNiKS0+d2Z4KSk7CglJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCYoKmlwcGRzYiktPmxvY2spOwoJLyogcmVnaXN0ZXIgYnVmZmVyICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCXsKCQlJRGlyZWN0U291bmRCdWZmZXJJbXBsICoqbmV3YnVmZmVycyA9IChJRGlyZWN0U291bmRCdWZmZXJJbXBsKiopSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPmJ1ZmZlcnMsc2l6ZW9mKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKikqKFRoaXMtPm5yb2ZidWZmZXJzKzEpKTsKCQlpZiAobmV3YnVmZmVycykgewoJCQlUaGlzLT5idWZmZXJzID0gbmV3YnVmZmVyczsKCQkJVGhpcy0+YnVmZmVyc1tUaGlzLT5ucm9mYnVmZmVyc10gPSAqaXBwZHNiOwoJCQlUaGlzLT5ucm9mYnVmZmVycysrOwoJCQlUUkFDRSgiYnVmZmVyIGNvdW50IGlzIG5vdyAlZFxuIiwgVGhpcy0+bnJvZmJ1ZmZlcnMpOwoJCX0gZWxzZSB7CgkJCUVSUigib3V0IG9mIG1lbW9yeSBmb3IgYnVmZmVyIGxpc3QhIEN1cnJlbnQgYnVmZmVyIGNvdW50IGlzICVkXG4iLCBUaGlzLT5ucm9mYnVmZmVycyk7CgkJCS8qIEZJWE1FOiByZWxlYXNlIGJ1ZmZlciAqLwoJCX0KCX0KCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJSURpcmVjdFNvdW5kX0FkZFJlZihpZmFjZSk7CglyZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9HZXRDYXBzKExQRElSRUNUU09VTkQgaWZhY2UsTFBEU0NBUFMgY2FwcykgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcClcbiIsVGhpcyxjYXBzKTsKCVRSQUNFKCIoZmxhZ3M9MHglMDhseClcbiIsY2Fwcy0+ZHdGbGFncyk7CgoJaWYgKGNhcHMgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qIFdlIHNob3VsZCBjaGVjayB0aGlzIHZhbHVlLCBub3Qgc2V0IGl0LiBTZWUgSW5zaWRlIERpcmVjdFgsIHAyMTUuICovCgljYXBzLT5kd1NpemUgPSBzaXplb2YoKmNhcHMpOwoKCWNhcHMtPmR3RmxhZ3MgPSBUaGlzLT5kcnZjYXBzLmR3RmxhZ3M7CgoJLyogRklYTUU6IGNvcHkgY2FwcyBmcm9tIFRoaXMtPmRydmNhcHMgKi8KCWNhcHMtPmR3TWluU2Vjb25kYXJ5U2FtcGxlUmF0ZQkJPSBEU0JGUkVRVUVOQ1lfTUlOOwoJY2Fwcy0+ZHdNYXhTZWNvbmRhcnlTYW1wbGVSYXRlCQk9IERTQkZSRVFVRU5DWV9NQVg7CgoJY2Fwcy0+ZHdQcmltYXJ5QnVmZmVycwkJCT0gMTsKCgljYXBzLT5kd01heEh3TWl4aW5nQWxsQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdNYXhId01peGluZ1N0YXRpY0J1ZmZlcnMJPSAwOwoJY2Fwcy0+ZHdNYXhId01peGluZ1N0cmVhbWluZ0J1ZmZlcnMJPSAwOwoKCWNhcHMtPmR3RnJlZUh3TWl4aW5nQWxsQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdGcmVlSHdNaXhpbmdTdGF0aWNCdWZmZXJzCT0gMDsKCWNhcHMtPmR3RnJlZUh3TWl4aW5nU3RyZWFtaW5nQnVmZmVycwk9IDA7CgoJY2Fwcy0+ZHdNYXhIdzNEQWxsQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdNYXhIdzNEU3RhdGljQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdNYXhIdzNEU3RyZWFtaW5nQnVmZmVycwkJPSAwOwoKCWNhcHMtPmR3RnJlZUh3M0RBbGxCdWZmZXJzCQk9IDA7CgljYXBzLT5kd0ZyZWVIdzNEU3RhdGljQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdGcmVlSHczRFN0cmVhbWluZ0J1ZmZlcnMJPSAwOwoKCWNhcHMtPmR3VG90YWxId01lbUJ5dGVzCQkJPSAwOwoKCWNhcHMtPmR3RnJlZUh3TWVtQnl0ZXMJCQk9IDA7CgoJY2Fwcy0+ZHdNYXhDb250aWdGcmVlSHdNZW1CeXRlcwkJPSAwOwoKCWNhcHMtPmR3VW5sb2NrVHJhbnNmZXJSYXRlSHdCdWZmZXJzCT0gNDA5NjsJLyogQnV0IHdlIGhhdmUgbm9uZS4uLiAqLwoKCWNhcHMtPmR3UGxheUNwdU92ZXJoZWFkU3dCdWZmZXJzCT0gMTsJLyogMSUgKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORCBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkQgaWZhY2UpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLCByZWYgd2FzICVsZFxuIixUaGlzLFRoaXMtPnJlZik7CglpZiAoIS0tKFRoaXMtPnJlZikpIHsKCQlVSU5UIGk7CgoJCXRpbWVLaWxsRXZlbnQoVGhpcy0+dGltZXJJRCk7CgkJdGltZUVuZFBlcmlvZChEU19USU1FX1JFUyk7CgoJCWlmIChwcmltYXJ5YnVmKQoJCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilwcmltYXJ5YnVmKTsKCgkJaWYgKFRoaXMtPmJ1ZmZlcnMpIHsKCQkJZm9yKCBpPTA7aTxUaGlzLT5ucm9mYnVmZmVycztpKyspCQoJCQkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+YnVmZmVyc1tpXSk7CgkJfQoKCQlpZiAoVGhpcy0+cHJpbWFyeSkKCQkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+cHJpbWFyeSk7CgoJCURlbGV0ZUNyaXRpY2FsU2VjdGlvbigmVGhpcy0+bG9jayk7CgkJaWYgKFRoaXMtPmRyaXZlcikgewoJCQlJRHNEcml2ZXJfQ2xvc2UoVGhpcy0+ZHJpdmVyKTsKCQl9IGVsc2UgewoJCQl1bnNpZ25lZCBjOwoJCQlmb3IgKGM9MDsgYzxEU19IRUxfRlJBR1M7IGMrKykKCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5wd2F2ZVtjXSk7CgkJfQoJCWlmIChUaGlzLT5kcnZkZXNjLmR3RmxhZ3MgJiBEU0RERVNDX0RPTU1TWVNURU1PUEVOKSB7CgkJCXdhdmVPdXRDbG9zZShUaGlzLT5od28pOwoJCX0KCQlpZiAoVGhpcy0+ZHJpdmVyKQoJCQlJRHNEcml2ZXJfUmVsZWFzZShUaGlzLT5kcml2ZXIpOwoKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkJZHNvdW5kID0gTlVMTDsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX1NldFNwZWFrZXJDb25maWcoCglMUERJUkVDVFNPVU5EIGlmYWNlLERXT1JEIGNvbmZpZwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCUZJWE1FKCIoJXAsMHglMDhseCk6c3R1YlxuIixUaGlzLGNvbmZpZyk7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORCBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kM0RMaXN0ZW5lciwgcmlpZCApICkgewoKCQlpZiAoVGhpcy0+bGlzdGVuZXIpIHsKCQkJKnBwb2JqID0gVGhpcy0+bGlzdGVuZXI7CgkJCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RMSVNURU5FUilUaGlzLT5saXN0ZW5lcik7CgkJCXJldHVybiBEU19PSzsKCQl9CgoJCVRoaXMtPmxpc3RlbmVyID0gKElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsKilIZWFwQWxsb2MoCgkJCUdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqKFRoaXMtPmxpc3RlbmVyKSkpOwoJCVRoaXMtPmxpc3RlbmVyLT5yZWYgPSAxOwoJCUlDT01fVlRCTChUaGlzLT5saXN0ZW5lcikgPSAmZHMzZGx2dDsKCQkqcHBvYmogPSAoTFBWT0lEKVRoaXMtPmxpc3RlbmVyOwoJCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RMSVNURU5FUikqcHBvYmopOwkKCgkJVGhpcy0+bGlzdGVuZXItPmRzYiA9IE5VTEw7IAoKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwuZHdTaXplID0gc2l6ZW9mKERTM0RMSVNURU5FUik7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZQb3NpdGlvbi51MS54ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52UG9zaXRpb24udTIueSA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlBvc2l0aW9uLnUzLnogPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZWZWxvY2l0eS51MS54ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52VmVsb2NpdHkudTIueSA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlZlbG9jaXR5LnUzLnogPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRGcm9udC51MS54ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50RnJvbnQudTIueSA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudEZyb250LnUzLnogPSAxLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRUb3AudTEueCA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudFRvcC51Mi55ID0gMS4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50VG9wLnUzLnogPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLmZsRGlzdGFuY2VGYWN0b3IgPSBEUzNEX0RFRkFVTFRESVNUQU5DRUZBQ1RPUjsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwuZmxSb2xsb2ZmRmFjdG9yID0gRFMzRF9ERUZBVUxUUk9MTE9GRkZBQ1RPUjsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwuZmxEb3BwbGVyRmFjdG9yID0gRFMzRF9ERUZBVUxURE9QUExFUkZBQ1RPUjsKCgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmVGhpcy0+bGlzdGVuZXItPmxvY2spOwoKCQlyZXR1cm4gRFNfT0s7Cgl9CgoJRklYTUUoIiglcCwlcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0NvbXBhY3QoCglMUERJUkVDVFNPVU5EIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0dldFNwZWFrZXJDb25maWcoCglMUERJUkVDVFNPVU5EIGlmYWNlLAoJTFBEV09SRCBscGR3U3BlYWtlckNvbmZpZykKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwgJXApXG4iLCBUaGlzLCBscGR3U3BlYWtlckNvbmZpZyk7CgkqbHBkd1NwZWFrZXJDb25maWcgPSBEU1NQRUFLRVJfU1RFUkVPIHwgKERTU1BFQUtFUl9HRU9NRVRSWV9OQVJST1cgPDwgMTYpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9Jbml0aWFsaXplKAoJTFBESVJFQ1RTT1VORCBpZmFjZSwKCUxQQ0dVSUQgbHBjR3VpZCkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwgJXApXG4iLCBUaGlzLCBscGNHdWlkKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZCkgZHN2dCA9IAp7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJSURpcmVjdFNvdW5kSW1wbF9RdWVyeUludGVyZmFjZSwKCUlEaXJlY3RTb3VuZEltcGxfQWRkUmVmLAoJSURpcmVjdFNvdW5kSW1wbF9SZWxlYXNlLAoJSURpcmVjdFNvdW5kSW1wbF9DcmVhdGVTb3VuZEJ1ZmZlciwKCUlEaXJlY3RTb3VuZEltcGxfR2V0Q2FwcywKCUlEaXJlY3RTb3VuZEltcGxfRHVwbGljYXRlU291bmRCdWZmZXIsCglJRGlyZWN0U291bmRJbXBsX1NldENvb3BlcmF0aXZlTGV2ZWwsCglJRGlyZWN0U291bmRJbXBsX0NvbXBhY3QsCglJRGlyZWN0U291bmRJbXBsX0dldFNwZWFrZXJDb25maWcsCglJRGlyZWN0U291bmRJbXBsX1NldFNwZWFrZXJDb25maWcsCglJRGlyZWN0U291bmRJbXBsX0luaXRpYWxpemUKfTsKCgpzdGF0aWMgdm9pZCBEU09VTkRfQ2hlY2tFdmVudChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIGludCBsZW4pCnsKCWludAkJCWk7CglEV09SRAkJCW9mZnNldDsKCUxQRFNCUE9TSVRJT05OT1RJRlkJZXZlbnQ7CgoJaWYgKGRzYi0+bnJvZm5vdGlmaWVzID09IDApCgkJcmV0dXJuOwoKCVRSQUNFKCIoJXApIGJ1ZmxlbiA9ICVsZCwgcGxheXBvcyA9ICVsZCwgbGVuID0gJWRcbiIsCgkJZHNiLCBkc2ItPmJ1ZmxlbiwgZHNiLT5wbGF5cG9zLCBsZW4pOwoJZm9yIChpID0gMDsgaSA8IGRzYi0+bnJvZm5vdGlmaWVzIDsgaSsrKSB7CgkJZXZlbnQgPSBkc2ItPm5vdGlmaWVzICsgaTsKCQlvZmZzZXQgPSBldmVudC0+ZHdPZmZzZXQ7CgkJVFJBQ0UoImNoZWNraW5nICVkLCBwb3NpdGlvbiAlbGQsIGV2ZW50ID0gJWRcbiIsCgkJCWksIG9mZnNldCwgZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJLyogRFNCUE5fT0ZGU0VUU1RPUCBoYXMgdG8gYmUgdGhlIGxhc3QgZWxlbWVudC4gU28gdGhpcyBpcyAqLwoJCS8qIE9LLiBbSW5zaWRlIERpcmVjdFgsIHAyNzRdICovCgkJLyogICovCgkJLyogVGhpcyBhbHNvIG1lYW5zIHdlIGNhbid0IHNvcnQgdGhlIGVudHJpZXMgYnkgb2Zmc2V0LCAqLwoJCS8qIGJlY2F1c2UgRFNCUE5fT0ZGU0VUU1RPUCA9PSAtMSAqLwoJCWlmIChvZmZzZXQgPT0gRFNCUE5fT0ZGU0VUU1RPUCkgewoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJWQgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlyZXR1cm47CgkJCX0gZWxzZQoJCQkJcmV0dXJuOwoJCX0KCQlpZiAoKGRzYi0+cGxheXBvcyArIGxlbikgPj0gZHNiLT5idWZsZW4pIHsKCQkJaWYgKChvZmZzZXQgPCAoKGRzYi0+cGxheXBvcyArIGxlbikgJSBkc2ItPmJ1ZmxlbikpIHx8CgkJCSAgICAob2Zmc2V0ID49IGRzYi0+cGxheXBvcykpIHsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJWQgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgob2Zmc2V0ID49IGRzYi0+cGxheXBvcykgJiYgKG9mZnNldCA8IChkc2ItPnBsYXlwb3MgKyBsZW4pKSkgewoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlZCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfQoJfQp9CgovKiBXQVYgZm9ybWF0IGluZm8gY2FuIGJlIGZvdW5kIGF0OiAqLwovKiAqLwovKglodHRwOi8vd3d3LmN3aS5ubC9mdHAvYXVkaW8vQXVkaW9Gb3JtYXRzLnBhcnQyICovCi8qCWZ0cDovL2Z0cC5jd2kubmwvcHViL2F1ZGlvL1JJRkYtZm9ybWF0ICovCi8qICovCi8qIEltcG9ydCBwb2ludHMgdG8gcmVtZW1iZXI6ICovCi8qICovCi8qCTgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwovKgkxNi1iaXQgV0FWIGlzIHNpZ25lZCAqLwoKc3RhdGljIGlubGluZSBJTlQxNiBjdnRVOHRvUzE2KEJZVEUgYnl0ZSkKewoJSU5UMTYJcyA9IChieXRlIC0gMTI4KSA8PCA4OwoKCXJldHVybiBzOwp9CgpzdGF0aWMgaW5saW5lIEJZVEUgY3Z0UzE2dG9VOChJTlQxNiB3b3JkKQp7CglCWVRFCWIgPSAod29yZCArIDMyNzY4KSA+PiA4OwoJCglyZXR1cm4gYjsKfQoKCi8qIFdlIHNob3VsZCBiZSBhYmxlIHRvIG9wdGltaXplIHRoZXNlIHR3byBpbmxpbmUgZnVuY3Rpb25zICovCi8qIHNvIHRoYXQgd2UgYXJlbid0IGRvaW5nIDgtPjE2LT44IGNvbnZlcnNpb25zIHdoZW4gaXQgaXMgKi8KLyogbm90IG5lY2Vzc2FyeS4gQnV0IHRoaXMgaXMgc3RpbGwgYSBXSVAuIE9wdGltaXplIGxhdGVyLiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZ2V0X2ZpZWxkcyhjb25zdCBJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIEJZVEUgKmJ1ZiwgSU5UICpmbCwgSU5UICpmcikKewoJSU5UMTYJKmJ1ZnMgPSAoSU5UMTYgKikgYnVmOwoKCS8qIFRSQUNFKCIoJXApXG4iLCBidWYpOyAqLwoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMikgewoJCSpmbCA9IGN2dFU4dG9TMTYoKmJ1Zik7CgkJKmZyID0gY3Z0VTh0b1MxNigqKGJ1ZiArIDEpKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgJiYgZHNiLT53ZngubkNoYW5uZWxzID09IDIpIHsKCQkqZmwgPSAqYnVmczsKCQkqZnIgPSAqKGJ1ZnMgKyAxKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMSkgewoJCSpmbCA9IGN2dFU4dG9TMTYoKmJ1Zik7CgkJKmZyID0gKmZsOwoJCXJldHVybjsKCX0KCglpZiAoKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMSkgewoJCSpmbCA9ICpidWZzOwoJCSpmciA9ICpidWZzOwoJCXJldHVybjsKCX0KCglGSVhNRSgiZ2V0X2ZpZWxkcyBmb3VuZCBhbiB1bnN1cHBvcnRlZCBjb25maWd1cmF0aW9uXG4iKTsKCXJldHVybjsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9maWVsZHMoQllURSAqYnVmLCBJTlQgZmwsIElOVCBmcikKewoJSU5UMTYgKmJ1ZnMgPSAoSU5UMTYgKikgYnVmOwoKCWlmICgocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDgpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDIpKSB7CgkJKmJ1ZiA9IGN2dFMxNnRvVTgoZmwpOwoJCSooYnVmICsgMSkgPSBjdnRTMTZ0b1U4KGZyKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDIpKSB7CgkJKmJ1ZnMgPSBmbDsKCQkqKGJ1ZnMgKyAxKSA9IGZyOwoJCXJldHVybjsKCX0KCglpZiAoKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAxKSkgewoJCSpidWYgPSBjdnRTMTZ0b1U4KChmbCArIGZyKSA+PiAxKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDEpKSB7CgkJKmJ1ZnMgPSAoZmwgKyBmcikgPj4gMTsKCQlyZXR1cm47Cgl9CglGSVhNRSgic2V0X2ZpZWxkcyBmb3VuZCBhbiB1bnN1cHBvcnRlZCBjb25maWd1cmF0aW9uXG4iKTsKCXJldHVybjsKfQoKLyogTm93IHdpdGggUGVyZmVjdFBpdGNoICh0bSkgdGVjaG5vbG9neSAqLwpzdGF0aWMgSU5UIERTT1VORF9NaXhlck5vcm0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBzaXplLCBpcG9zLCBpbGVuLCBmaWVsZEwsIGZpZWxkUjsKCUJZVEUJKmlicCwgKm9icDsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoKCWlicCA9IGRzYi0+YnVmZmVyICsgZHNiLT5idWZfbWl4cG9zOwoJb2JwID0gYnVmOwoKCVRSQUNFKCIoJXAsICVwLCAlcCksIGJ1Zl9taXhwb3M9JWxkXG4iLCBkc2IsIGlicCwgb2JwLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogQ2hlY2sgZm9yIHRoZSBiZXN0IGNhc2UgKi8KCWlmICgoZHNiLT5mcmVxID09IHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYykgJiYKCSAgICAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlKSAmJgoJICAgIChkc2ItPndmeC5uQ2hhbm5lbHMgPT0gcHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscykpIHsKCSAgICAgICAgRFdPUkQgYnl0ZXNsZWZ0ID0gZHNiLT5idWZsZW4gLSBkc2ItPmJ1Zl9taXhwb3M7CgkJVFJBQ0UoIiglcCkgQmVzdCBjYXNlXG4iLCBkc2IpOwoJICAgIAlpZiAobGVuIDw9IGJ5dGVzbGVmdCApCgkJCW1lbWNweShvYnAsIGlicCwgbGVuKTsKCQllbHNlIHsgLyogd3JhcCAqLwoJCQltZW1jcHkob2JwLCBpYnAsIGJ5dGVzbGVmdCApOwoJCQltZW1jcHkob2JwICsgYnl0ZXNsZWZ0LCBkc2ItPmJ1ZmZlciwgbGVuIC0gYnl0ZXNsZWZ0KTsKCQl9CgkJcmV0dXJuIGxlbjsKCX0KCQoJLyogQ2hlY2sgZm9yIHNhbWUgc2FtcGxlIHJhdGUgKi8KCWlmIChkc2ItPmZyZXEgPT0gcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjKSB7CgkJVFJBQ0UoIiglcCkgU2FtZSBzYW1wbGUgcmF0ZSAlbGQgPSBwcmltYXJ5ICVsZFxuIiwgZHNiLAoJCQlkc2ItPmZyZXEsIHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYyk7CgkJaWxlbiA9IDA7CgkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSBvQWR2YW5jZSkgewoJCQlnZXRfZmllbGRzKGRzYiwgaWJwLCAmZmllbGRMLCAmZmllbGRSKTsKCQkJaWJwICs9IGlBZHZhbmNlOwoJCQlpbGVuICs9IGlBZHZhbmNlOwoJCQlzZXRfZmllbGRzKG9icCwgZmllbGRMLCBmaWVsZFIpOwoJCQlvYnAgKz0gb0FkdmFuY2U7CgkJCWlmIChpYnAgPj0gKEJZVEUgKikoZHNiLT5idWZmZXIgKyBkc2ItPmJ1ZmxlbikpCgkJCQlpYnAgPSBkc2ItPmJ1ZmZlcjsJLyogd3JhcCAqLwoJCX0KCQlyZXR1cm4gKGlsZW4pOwkKCX0KCgkvKiBNaXggaW4gZGlmZmVyZW50IHNhbXBsZSByYXRlcyAqLwoJLyogKi8KCS8qIE5ldyBQZXJmZWN0UGl0Y2godG0pIFRlY2hub2xvZ3kgKGMpIDE5OTggUm9iIFJpZ2dzICovCgkvKiBQYXRlbnQgUGVuZGluZyA6LV0gKi8KCgkvKiBQYXRlbnQgZW5oYW5jZW1lbnRzIChjKSAyMDAwIE92ZSBL5XZlbiwKCSAqIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuICovCgoJVFJBQ0UoIiglcCkgQWRqdXN0aW5nIGZyZXF1ZW5jeTogJWxkIC0+ICVsZFxuIiwKCQlkc2IsIGRzYi0+ZnJlcSwgcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjKTsKCglzaXplID0gbGVuIC8gb0FkdmFuY2U7CglpbGVuID0gMDsKCWlwb3MgPSBkc2ItPmJ1Zl9taXhwb3M7Cglmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJZ2V0X2ZpZWxkcyhkc2IsIChkc2ItPmJ1ZmZlciArIGlwb3MpLCAmZmllbGRMLCAmZmllbGRSKTsKCQlzZXRfZmllbGRzKG9icCwgZmllbGRMLCBmaWVsZFIpOwoJCW9icCArPSBvQWR2YW5jZTsKCgkJZHNiLT5mcmVxQWNjICs9IGRzYi0+ZnJlcUFkanVzdDsKCQlpZiAoZHNiLT5mcmVxQWNjID49ICgxPDxEU09VTkRfRlJFUVNISUZUKSkgewoJCQlVTE9ORyBhZHYgPSAoZHNiLT5mcmVxQWNjPj5EU09VTkRfRlJFUVNISUZUKSAqIGlBZHZhbmNlOwoJCQlkc2ItPmZyZXFBY2MgJj0gKDE8PERTT1VORF9GUkVRU0hJRlQpLTE7CgkJCWlwb3MgKz0gYWR2OyBpbGVuICs9IGFkdjsKCQkJd2hpbGUgKGlwb3MgPj0gZHNiLT5idWZsZW4pCgkJCQlpcG9zIC09IGRzYi0+YnVmbGVuOwoJCX0KCX0KCXJldHVybiBpbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4ZXJWb2woSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBpbmMgPSBwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPj4gMzsKCUJZVEUJKmJwYyA9IGJ1ZjsKCUlOVDE2CSpicHMgPSAoSU5UMTYgKikgYnVmOwoJCglUUkFDRSgiKCVwKSBsZWZ0ID0gJWx4LCByaWdodCA9ICVseFxuIiwgZHNiLAoJCWRzYi0+dm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yLCBkc2ItPnZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwoJaWYgKCghKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fCAoZHNiLT52b2xwYW4ubFBhbiA9PSAwKSkgJiYKCSAgICAoIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkgfHwgKGRzYi0+dm9scGFuLmxWb2x1bWUgPT0gMCkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSkKCQlyZXR1cm47CQkvKiBOb3RoaW5nIHRvIGRvICovCgoJLyogSWYgd2UgZW5kIHVwIHdpdGggc29tZSBib3pvIGNvZGVyIHVzaW5nIHBhbm5pbmcgb3IgM0Qgc291bmQgKi8KCS8qIHdpdGggYSBtb25vIHByaW1hcnkgYnVmZmVyLCBpdCBjb3VsZCBzb3VuZCB2ZXJ5IHdlaXJkIHVzaW5nICovCgkvKiB0aGlzIG1ldGhvZC4gT2ggd2VsbCwgdG91Z2ggcGF0b290aWVzLiAqLwoKCWZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gaW5jKSB7CgkJSU5UCXZhbDsKCgkJc3dpdGNoIChpbmMpIHsKCgkJY2FzZSAxOgoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQsIGJ1dCB3ZSBuZWVkIHRvIG9wZXJhdGUgKi8KCQkJLyogb24gc2lnbmVkIGRhdGEgZm9yIHRoaXMgdG8gd29yayBwcm9wZXJseSAqLwoJCQl2YWwgPSAqYnBjIC0gMTI4OwoJCQl2YWwgPSAoKHZhbCAqIChpICYgaW5jID8gZHNiLT52b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yIDogZHNiLT52b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpKSA+PiAxNik7CgkJCSpicGMgPSB2YWwgKyAxMjg7CgkJCWJwYysrOwoJCQlicmVhazsKCQljYXNlIDI6CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkIC0tIG11Y2ggYmV0dGVyICovCgkJCXZhbCA9ICpicHM7CgkJCXZhbCA9ICgodmFsICogKChpICYgaW5jKSA/IGRzYi0+dm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3RvciA6IGRzYi0+dm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSkgPj4gMTYpOwoJCQkqYnBzID0gdmFsOwoJCQlicHMrKzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJLyogVmVyeSB1Z2x5ISAqLwoJCQlGSVhNRSgiTWl4ZXJWb2wgaGFkIGEgbmFzdHkgZXJyb3JcbiIpOwoJCX0KCX0JCQp9CgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyB2b2lkIERTT1VORF9NaXhlcjNEKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgbGVuKQp7CglCWVRFCSppYnAsICpvYnA7CglEV09SRAlidWZsZW4sIGJ1Zl9taXhwb3M7CgoJYnVmbGVuID0gZHNiLT5kczNkYi0+YnVmbGVuOwoJYnVmX21peHBvcyA9IChkc2ItPmJ1Zl9taXhwb3MgKiBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ24pIC8gZHNiLT53ZngubkJsb2NrQWxpZ247CglpYnAgPSBkc2ItPmRzM2RiLT5idWZmZXIgKyBidWZfbWl4cG9zOwoJb2JwID0gYnVmOwoKCWlmIChidWZfbWl4cG9zID4gYnVmbGVuKSB7CgkJRklYTUUoIk1ham9yIGJyZWFrYWdlXG4iKTsKCQlyZXR1cm47Cgl9CgoJaWYgKGxlbiA8PSAoYnVmX21peHBvcyArIGJ1ZmxlbikpCgkJbWVtY3B5KG9icCwgaWJwLCBsZW4pOwoJZWxzZSB7IC8qIHdyYXAgKi8KCQltZW1jcHkob2JwLCBpYnAsIGJ1ZmxlbiAtIGJ1Zl9taXhwb3MpOwoJCW1lbWNweShvYnAgKyAoYnVmbGVuIC0gYnVmX21peHBvcyksCgkJICAgIGRzYi0+YnVmZmVyLAoJCSAgICBsZW4gLSAoYnVmbGVuIC0gYnVmX21peHBvcykpOwoJfQoJcmV0dXJuOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQgKnRtcF9idWZmZXI7CnN0YXRpYyBzaXplX3QgdG1wX2J1ZmZlcl9sZW4gPSAwOwoKc3RhdGljIHZvaWQgKkRTT1VORF90bXBidWZmZXIoc2l6ZV90IGxlbikKewogIGlmIChsZW4+dG1wX2J1ZmZlcl9sZW4pIHsKICAgIHZvaWQgKm5ld19idWZmZXIgPSByZWFsbG9jKHRtcF9idWZmZXIsIGxlbik7CiAgICBpZiAobmV3X2J1ZmZlcikgewogICAgICB0bXBfYnVmZmVyID0gbmV3X2J1ZmZlcjsKICAgICAgdG1wX2J1ZmZlcl9sZW4gPSBsZW47CiAgICB9CiAgICByZXR1cm4gbmV3X2J1ZmZlcjsKICB9CiAgcmV0dXJuIHRtcF9idWZmZXI7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4SW5CdWZmZXIoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgZnJhZ2xlbikKewoJSU5UCWksIGxlbiwgaWxlbiwgdGVtcCwgZmllbGQ7CglJTlQJYWR2YW5jZSA9IHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA+PiAzOwoJQllURQkqYnVmLCAqaWJ1ZiwgKm9idWY7CglJTlQxNgkqaWJ1ZnMsICpvYnVmczsKCglsZW4gPSBmcmFnbGVuOwoJaWYgKCEoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpKSB7CgkJdGVtcCA9IE11bERpdihwcmltYXJ5YnVmLT53ZngubkF2Z0J5dGVzUGVyU2VjLCBkc2ItPmJ1ZmxlbiwKCQkJZHNiLT5uQXZnQnl0ZXNQZXJTZWMpIC0KCQkgICAgICAgTXVsRGl2KHByaW1hcnlidWYtPndmeC5uQXZnQnl0ZXNQZXJTZWMsIGRzYi0+YnVmX21peHBvcywKCQkJZHNiLT5uQXZnQnl0ZXNQZXJTZWMpOwoJCWxlbiA9IChsZW4gPiB0ZW1wKSA/IHRlbXAgOiBsZW47Cgl9CglsZW4gJj0gfjM7CQkJCS8qIDQgYnl0ZSBhbGlnbm1lbnQgKi8KCglpZiAobGVuID09IDApIHsKCQkvKiBUaGlzIHNob3VsZCBvbmx5IGhhcHBlbiBpZiB3ZSBhcmVuJ3QgbG9vcGluZyBhbmQgdGVtcCA8IDQgKi8KCgkJLyogV2Ugc2tpcCB0aGUgcmVtYWluZGVyLCBzbyBjaGVjayBmb3IgcG9zc2libGUgZXZlbnRzICovCgkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCBkc2ItPmJ1ZmxlbiAtIGRzYi0+YnVmX21peHBvcyk7CgkJLyogU3RvcCAqLwoJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCWRzYi0+cGxheXBvcyA9IDA7CgkJZHNiLT5idWZfbWl4cG9zID0gMDsKCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJCS8qIENoZWNrIGZvciBEU0JQTl9PRkZTRVRTVE9QICovCgkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCAwKTsKCQlyZXR1cm4gMDsKCX0KCgkvKiBCZWVuIHNlZWluZyBzZWdmYXVsdHMgaW4gbWFsbG9jKCkgZm9yIHNvbWUgcmVhc29uLi4uICovCglUUkFDRSgiYWxsb2NhdGluZyBidWZmZXIgKHNpemUgPSAlZClcbiIsIGxlbik7CglpZiAoKGJ1ZiA9IGlidWYgPSAoQllURSAqKSBEU09VTkRfdG1wYnVmZmVyKGxlbikpID09IE5VTEwpCgkJcmV0dXJuIDA7CgoJVFJBQ0UoIk1peEluQnVmZmVyICglcCkgbGVuID0gJWQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJb2J1ZiA9IHByaW1hcnlidWYtPmJ1ZmZlciArIHdyaXRlcG9zOwoJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSBhZHZhbmNlKSB7CgkJb2J1ZnMgPSAoSU5UMTYgKikgb2J1ZjsKCQlpYnVmcyA9IChJTlQxNiAqKSBpYnVmOwoJCWlmIChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCkgewoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KCQkJZmllbGQgPSAoKmlidWYgLSAxMjgpOwoJCQlmaWVsZCArPSAoKm9idWYgLSAxMjgpOwoJCQlmaWVsZCA9IGZpZWxkID4gMTI3ID8gMTI3IDogZmllbGQ7CgkJCWZpZWxkID0gZmllbGQgPCAtMTI4ID8gLTEyOCA6IGZpZWxkOwoJCQkqb2J1ZiA9IGZpZWxkICsgMTI4OwoJCX0gZWxzZSB7CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCWZpZWxkID0gKmlidWZzOwoJCQlmaWVsZCArPSAqb2J1ZnM7CgkJCWZpZWxkID0gZmllbGQgPiAzMjc2NyA/IDMyNzY3IDogZmllbGQ7CgkJCWZpZWxkID0gZmllbGQgPCAtMzI3NjggPyAtMzI3NjggOiBmaWVsZDsKCQkJKm9idWZzID0gZmllbGQ7CgkJfQoJCWlidWYgKz0gYWR2YW5jZTsKCQlvYnVmICs9IGFkdmFuY2U7CgkJaWYgKG9idWYgPj0gKEJZVEUgKikocHJpbWFyeWJ1Zi0+YnVmZmVyICsgcHJpbWFyeWJ1Zi0+YnVmbGVuKSkKCQkJb2J1ZiA9IHByaW1hcnlidWYtPmJ1ZmZlcjsKCX0KCS8qIGZyZWUoYnVmKTsgKi8KCglpZiAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQT1NJVElPTk5PVElGWSkKCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIGlsZW4pOwoKCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA+IGRzYi0+YnVmX21peHBvcykgJiYgKGRzYi0+c3RhcnRwb3MgPD0gZHNiLT5idWZfbWl4cG9zICsgaWxlbikpIHsKCQkvKiBIQUNLLi4uIGxlYWRpbiBzaG91bGQgYmUgcmVzZXQgd2hlbiB0aGUgUExBWSBwb3NpdGlvbiByZWFjaGVzIHRoZSBzdGFydHBvcywKCQkgKiBub3QgdGhlIE1JWCBwb3NpdGlvbi4uLiBidXQgaWYgdGhlIHNvdW5kIGJ1ZmZlciBpcyBiaWdnZXIgdGhhbiBvdXIgcHJlYnVmZmVyaW5nCgkJICogKHdoaWNoIG11c3QgYmUgdGhlIGNhc2UgZm9yIHRoZSBzdHJlYW1pbmcgYnVmZmVycyB0aGF0IG5lZWQgdGhpcyBoYWNrIGFueXdheSkKCQkgKiBwbHVzIERTX0hFTF9NQVJHSU4gb3IgZXF1aXZhbGVudCwgdGhlbiB0aGlzIG91Z2h0IHRvIHdvcmsgYW55d2F5LiAqLwoJCWRzYi0+bGVhZGluID0gRkFMU0U7Cgl9CgoJZHNiLT5idWZfbWl4cG9zICs9IGlsZW47CgkKCWlmIChkc2ItPmJ1Zl9taXhwb3MgPj0gZHNiLT5idWZsZW4pIHsKCQlpZiAoIShkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykpIHsKCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCWRzYi0+cGxheXBvcyA9IDA7CgkJCWRzYi0+YnVmX21peHBvcyA9IDA7CgkJCWRzYi0+bGVhZGluID0gRkFMU0U7CgkJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgMCk7CQkvKiBGb3IgRFNCUE5fT0ZGU0VUU1RPUCAqLwoJCX0gZWxzZSB7CgkJCS8qIHdyYXAgKi8KCQkJd2hpbGUgKGRzYi0+YnVmX21peHBvcyA+PSBkc2ItPmJ1ZmxlbikKCQkJCWRzYi0+YnVmX21peHBvcyAtPSBkc2ItPmJ1ZmxlbjsKCQkJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zIDw9IGRzYi0+YnVmX21peHBvcykpCgkJCQlkc2ItPmxlYWRpbiA9IEZBTFNFOyAvKiBIQUNLOiBzZWUgYWJvdmUgKi8KCQl9Cgl9CgoJcmV0dXJuIGxlbjsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peENhbmNlbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zKQp7CglGSVhNRSgicHJlYnVmZmVyIGNhbmNlbCBub3QgaW1wbGVtZW50ZWQgeWV0XG4iKTsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhPbmUoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCBwbGF5cG9zLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbWl4bGVuKQp7CglEV09SRCBsZW4sIHNsZW47CgkvKiBkZXRlcm1pbmUgdGhpcyBidWZmZXIncyB3cml0ZSBwb3NpdGlvbiAqLwoJRFdPUkQgYnVmX3dyaXRlcG9zID0gRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oZHNiLCBkc2ItPnN0YXRlICYgcHJpbWFyeWJ1Zi0+c3RhdGUsIHdyaXRlcG9zLAoJCQkJCQkgICAgIHdyaXRlcG9zLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogZGV0ZXJtaW5lIGhvdyBtdWNoIGFscmVhZHktbWl4ZWQgZGF0YSBleGlzdHMgKi8KCURXT1JEIGJ1Zl9kb25lID0KCQkoKGRzYi0+YnVmX21peHBvcyA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBidWZfd3JpdGVwb3M7CglEV09SRCBwcmltYXJ5X2RvbmUgPQoJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHdyaXRlcG9zKSA/IHByaW1hcnlidWYtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gd3JpdGVwb3M7CglEV09SRCBhZHZfZG9uZSA9CgkJKChwcmltYXJ5YnVmLT5idWZfbWl4cG9zIDwgd3JpdGVwb3MpID8gcHJpbWFyeWJ1Zi0+YnVmbGVuIDogMCkgKwoJCXByaW1hcnlidWYtPmJ1Zl9taXhwb3MgLSB3cml0ZXBvczsKCWludCBzdGlsbF9iZWhpbmQ7CgoJVFJBQ0UoImJ1Zl93cml0ZXBvcz0lbGQsIHByaW1hcnlfd3JpdGVwb3M9JWxkXG4iLCBidWZfd3JpdGVwb3MsIHdyaXRlcG9zKTsKCVRSQUNFKCJidWZfZG9uZT0lbGQsIHByaW1hcnlfZG9uZT0lbGRcbiIsIGJ1Zl9kb25lLCBwcmltYXJ5X2RvbmUpOwoJVFJBQ0UoImJ1Zl9taXhwb3M9JWxkLCBwcmltYXJ5X21peHBvcz0lbGQsIG1peGxlbj0lbGRcbiIsIGRzYi0+YnVmX21peHBvcywgZHNiLT5wcmltYXJ5X21peHBvcywKCSAgICAgIG1peGxlbik7CglUUkFDRSgibG9vcGluZz0lbGQsIHN0YXJ0cG9zPSVsZCwgbGVhZGluPSVsZFxuIiwgZHNiLT5wbGF5ZmxhZ3MsIGRzYi0+c3RhcnRwb3MsIGRzYi0+bGVhZGluKTsKCgkvKiBzYXZlIHdyaXRlIHBvc2l0aW9uIGZvciBub24tR0VUQ1VSUkVOVFBPU0lUSU9OMi4uLiAqLwoJZHNiLT5wbGF5cG9zID0gYnVmX3dyaXRlcG9zOwoKCS8qIGNoZWNrIHdoZXRoZXIgQ2FsY1BsYXlQb3NpdGlvbiBkZXRlY3RlZCBhIG1peGluZyB1bmRlcnJ1biAqLwoJaWYgKChidWZfZG9uZSA9PSAwKSAmJiAoZHNiLT5wcmltYXJ5X21peHBvcyAhPSB3cml0ZXBvcykpIHsKCQkvKiBpdCBkaWQsIGJ1dCBkaWQgd2UgaGF2ZSBtb3JlIHRvIHBsYXk/ICovCgkJaWYgKChkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykgfHwKCQkgICAgKGRzYi0+YnVmX21peHBvcyA8IGRzYi0+YnVmbGVuKSkgewoJCQkvKiB5ZXMsIGhhdmUgdG8gcmVjb3ZlciAqLwoJCQlFUlIoInVuZGVycnVuIG9uIHNvdW5kIGJ1ZmZlciAlcFxuIiwgZHNiKTsKCQkJVFJBQ0UoInJlY292ZXJpbmcgZnJvbSB1bmRlcnJ1bjogcHJpbWFyeV9taXhwb3M9JWxkXG4iLCB3cml0ZXBvcyk7CgkJfQoJCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCQlwcmltYXJ5X2RvbmUgPSAwOwoJfQoJLyogZGV0ZXJtaW5lIGhvdyBmYXIgYWhlYWQgd2Ugc2hvdWxkIG1peCAqLwoJaWYgKCgoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHx8CgkgICAgIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5wcm9iYWJseV92YWxpZF90byAhPSAwKSkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfU1RBVElDKSkgewoJCS8qIGlmIHRoaXMgaXMgYSBzdHJlYW1pbmcgYnVmZmVyLCBpdCB0eXBpY2FsbHkgbWVhbnMgdGhhdAoJCSAqIHdlIHNob3VsZCBkZWZlciBtaXhpbmcgcGFzdCBwcm9iYWJseV92YWxpZF90byBhcyBsb25nCgkJICogYXMgd2UgY2FuLCB0byBhdm9pZCB1bm5lY2Vzc2FyeSByZW1peGluZyAqLwoJCS8qIHRoZSBoZWF2eS1sb29raW5nIGNhbGN1bGF0aW9ucyBzaG91bGRuJ3QgYmUgdGhhdCBiYWQsCgkJICogYXMgYW55IGdhbWUgaXNuJ3QgbGlrZWx5IHRvIGJlIGhhdmUgbW9yZSB0aGFuIDEgb3IgMgoJCSAqIHN0cmVhbWluZyBidWZmZXJzIGluIHVzZSBhdCBhbnkgdGltZSBhbnl3YXkuLi4gKi8KCQlEV09SRCBwcm9iYWJseV92YWxpZF9sZWZ0ID0KCQkJKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPT0gKERXT1JEKS0xKSA/IGRzYi0+YnVmbGVuIDoKCQkJKChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIC0gYnVmX3dyaXRlcG9zOwoJCS8qIGNoZWNrIGZvciBsZWFkaW4gY29uZGl0aW9uICovCgkJaWYgKChwcm9iYWJseV92YWxpZF9sZWZ0ID09IDApICYmCgkJICAgIChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID09IGRzYi0+c3RhcnRwb3MpICYmCgkJICAgIGRzYi0+bGVhZGluKQoJCQlwcm9iYWJseV92YWxpZF9sZWZ0ID0gZHNiLT5idWZsZW47CgkJVFJBQ0UoInN0cmVhbWluZyBidWZmZXIgcHJvYmFibHlfdmFsaWRfdG89JWxkLCBwcm9iYWJseV92YWxpZF9sZWZ0PSVsZFxuIiwKCQkgICAgICBkc2ItPnByb2JhYmx5X3ZhbGlkX3RvLCBwcm9iYWJseV92YWxpZF9sZWZ0KTsKCQkvKiBjaGVjayB3aGV0aGVyIHRoZSBhcHAncyB0aW1lIGlzIGFscmVhZHkgdXAgKi8KCQlpZiAocHJvYmFibHlfdmFsaWRfbGVmdCA8IGRzYi0+d3JpdGVsZWFkKSB7CgkJCVdBUk4oInByb2JhYmx5X3ZhbGlkX3RvIG5vdyB3aXRoaW4gd3JpdGVsZWFkLCBwb3NzaWJsZSBzdHJlYW1pbmcgdW5kZXJydW5cbiIpOwoJCQkvKiBvbmNlIHdlIHBhc3MgdGhlIHBvaW50IG9mIG5vIHJldHVybiwKCQkJICogbm8gcmVhc29uIHRvIGhvbGQgYmFjayBhbnltb3JlICovCgkJCWRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPSAoRFdPUkQpLTE7CgkJCS8qIHdlIGp1c3QgaGF2ZSB0byBnbyBhaGVhZCBhbmQgbWl4IHdoYXQgd2UgaGF2ZSwKCQkJICogdGhlcmUncyBubyB0ZWxsaW5nIHdoYXQgdGhlIGFwcCBpcyB0aGlua2luZyBhbnl3YXkgKi8KCQl9IGVsc2UgewoJCQkvKiBkaXZpZGUgdmFsaWQgbGVuZ3RoIGJ5IG91ciBzYW1wbGUgc2l6ZSAqLwoJCQlwcm9iYWJseV92YWxpZF9sZWZ0IC89IGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJCQkvKiBhZGp1c3QgZm9yIG91ciBmcmVxdWVuY3kgKi8KCQkJcHJvYmFibHlfdmFsaWRfbGVmdCA9IChwcm9iYWJseV92YWxpZF9sZWZ0IDw8IERTT1VORF9GUkVRU0hJRlQpIC8gZHNiLT5mcmVxQWRqdXN0OwoJCQkvKiBtdWx0aXBseSBieSBwcmltYXJ5IHNhbXBsZSBzaXplICovCgkJCXByb2JhYmx5X3ZhbGlkX2xlZnQgKj0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoJCQkvKiBjaGVjayB3aGV0aGVyIHRvIGNsaXAgbWl4X2xlbiAqLwoJCQlpZiAocHJvYmFibHlfdmFsaWRfbGVmdCA8IG1peGxlbikgewoJCQkJVFJBQ0UoImNsaXBwaW5nIHRvIHByb2JhYmx5X3ZhbGlkX2xlZnQ9JWxkXG4iLCBwcm9iYWJseV92YWxpZF9sZWZ0KTsKCQkJCW1peGxlbiA9IHByb2JhYmx5X3ZhbGlkX2xlZnQ7CgkJCX0KCQl9Cgl9CgkvKiBjdXQgbWl4bGVuIHdpdGggd2hhdCdzIGFscmVhZHkgYmVlbiBtaXhlZCAqLwoJaWYgKG1peGxlbiA8IHByaW1hcnlfZG9uZSkgewoJCS8qIGh1aD8gYW5kIHN0aWxsIENhbGNQbGF5UG9zaXRpb24gZGlkbid0CgkJICogZGV0ZWN0IGFuIHVuZGVycnVuPyAqLwoJCUZJWE1FKCJwcm9ibGVtIHdpdGggdW5kZXJydW4gZGV0ZWN0aW9uIChtaXhsZW49JWxkIDwgcHJpbWFyeV9kb25lPSVsZClcbiIsIG1peGxlbiwgcHJpbWFyeV9kb25lKTsKCQlyZXR1cm4gMDsKCX0KCWxlbiA9IG1peGxlbiAtIHByaW1hcnlfZG9uZTsKCVRSQUNFKCJyZW1haW5pbmcgbWl4bGVuPSVsZFxuIiwgbGVuKTsKCglpZiAobGVuIDwgcHJpbWFyeWJ1Zi0+ZHNvdW5kLT5mcmFnbGVuKSB7CgkJLyogc21hbGxlciB0aGFuIGEgZnJhZ21lbnQsIHdhaXQgdW50aWwgaXQgZ2V0cyBsYXJnZXIKCQkgKiBiZWZvcmUgd2UgdGFrZSB0aGUgbWl4aW5nIG92ZXJoZWFkICovCgkJVFJBQ0UoIm1peGxlbiBub3Qgd29ydGggaXQsIGRlZmVycmluZyBtaXhpbmdcbiIpOwoJCXJldHVybiAwOwoJfQoKCS8qIG9rLCB3ZSBrbm93IGhvdyBtdWNoIHRvIG1peCwgbGV0J3MgZ28gKi8KCXN0aWxsX2JlaGluZCA9IChhZHZfZG9uZSA+IHByaW1hcnlfZG9uZSk7Cgl3aGlsZSAobGVuKSB7CgkJc2xlbiA9IHByaW1hcnlidWYtPmJ1ZmxlbiAtIGRzYi0+cHJpbWFyeV9taXhwb3M7CgkJaWYgKHNsZW4gPiBsZW4pIHNsZW4gPSBsZW47CgkJc2xlbiA9IERTT1VORF9NaXhJbkJ1ZmZlcihkc2IsIGRzYi0+cHJpbWFyeV9taXhwb3MsIHNsZW4pOwoKCQlpZiAoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBwcmltYXJ5YnVmLT5idWZfbWl4cG9zKSAmJgoJCSAgICAoZHNiLT5wcmltYXJ5X21peHBvcyArIHNsZW4gPj0gcHJpbWFyeWJ1Zi0+YnVmX21peHBvcykpCgkJCXN0aWxsX2JlaGluZCA9IEZBTFNFOwoKCQlkc2ItPnByaW1hcnlfbWl4cG9zICs9IHNsZW47IGxlbiAtPSBzbGVuOwoJCXdoaWxlIChkc2ItPnByaW1hcnlfbWl4cG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKCQkJZHNiLT5wcmltYXJ5X21peHBvcyAtPSBwcmltYXJ5YnVmLT5idWZsZW47CgoJCWlmICgoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB8fCAhc2xlbikgYnJlYWs7Cgl9CglUUkFDRSgibmV3IHByaW1hcnlfbWl4cG9zPSVsZCwgcHJpbWFyeV9hZHZiYXNlPSVsZFxuIiwgZHNiLT5wcmltYXJ5X21peHBvcywgcHJpbWFyeWJ1Zi0+YnVmX21peHBvcyk7CglUUkFDRSgibWl4ZWQgZGF0YSBsZW49JWxkLCBzdGlsbF9iZWhpbmQ9JWRcbiIsIG1peGxlbi1sZW4sIHN0aWxsX2JlaGluZCk7CgkvKiByZXR1cm4gaG93IGZhciB3ZSB0aGluayB0aGUgcHJpbWFyeSBidWZmZXIgY2FuCgkgKiBhZHZhbmNlIGl0cyB1bmRlcnJ1biBkZXRlY3Rvci4uLiovCglpZiAoc3RpbGxfYmVoaW5kKSByZXR1cm4gMDsKCWlmICgobWl4bGVuIC0gbGVuKSA8IHByaW1hcnlfZG9uZSkgcmV0dXJuIDA7CglzbGVuID0gKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgcHJpbWFyeWJ1Zi0+YnVmX21peHBvcykgPwoJCXByaW1hcnlidWYtPmJ1ZmxlbiA6IDApICsgZHNiLT5wcmltYXJ5X21peHBvcyAtCgkJcHJpbWFyeWJ1Zi0+YnVmX21peHBvczsKCWlmIChzbGVuID4gbWl4bGVuKSB7CgkJLyogdGhlIHByaW1hcnlfZG9uZSBhbmQgc3RpbGxfYmVoaW5kIGNoZWNrcyBhYm92ZSBzaG91bGQgaGF2ZSB3b3JrZWQgKi8KCQlGSVhNRSgicHJvYmxlbSB3aXRoIGFkdmFuY2VtZW50IGNhbGN1bGF0aW9uIChhZHZsZW49JWxkID4gbWl4bGVuPSVsZClcbiIsIHNsZW4sIG1peGxlbik7CgkJc2xlbiA9IDA7Cgl9CglyZXR1cm4gc2xlbjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhUb1ByaW1hcnkoRFdPUkQgcGxheXBvcywgRFdPUkQgd3JpdGVwb3MsIERXT1JEIG1peGxlbiwgQk9PTCByZWNvdmVyKQp7CglJTlQJCQlpLCBsZW4sIG1heGxlbiA9IDA7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsCSpkc2I7CgoJVFJBQ0UoIiglbGQsJWxkLCVsZClcbiIsIHBsYXlwb3MsIHdyaXRlcG9zLCBtaXhsZW4pOwoJZm9yIChpID0gZHNvdW5kLT5ucm9mYnVmZmVycyAtIDE7IGkgPj0gMDsgaS0tKSB7CgkJZHNiID0gZHNvdW5kLT5idWZmZXJzW2ldOwoKCQlpZiAoIWRzYiB8fCAhKElDT01fVlRCTChkc2IpKSkKCQkJY29udGludWU7CiAJCWlmIChkc2ItPmJ1ZmxlbiAmJiBkc2ItPnN0YXRlICYmICFkc2ItPmh3YnVmKSB7CgkJCVRSQUNFKCJDaGVja2luZyAlcCwgbWl4bGVuPSVsZFxuIiwgZHNiLCBtaXhsZW4pOwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJRFNPVU5EX01peENhbmNlbChkc2IsIHdyaXRlcG9zKTsKCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9IGVsc2UgewoJCQkJaWYgKChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fCByZWNvdmVyKQoJCQkJCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCQkJCWxlbiA9IERTT1VORF9NaXhPbmUoZHNiLCBwbGF5cG9zLCB3cml0ZXBvcywgbWl4bGVuKTsKCQkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKQoJCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQkJbWF4bGVuID0gKGxlbiA+IG1heGxlbikgPyBsZW4gOiBtYXhsZW47CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQl9Cgl9CgkKCXJldHVybiBtYXhsZW47Cn0KCnN0YXRpYyB2b2lkIENBTExCQUNLIERTT1VORF90aW1lcihVSU5UIHRpbWVySUQsIFVJTlQgbXNnLCBEV09SRCBkd1VzZXIsIERXT1JEIGR3MSwgRFdPUkQgZHcyKQp7CglpbnQgbmZpbGxlcjsKCUJPT0wgZm9yY2VkOwoJSFJFU1VMVCBocmVzOwoKCWlmICghZHNvdW5kIHx8ICFwcmltYXJ5YnVmKSB7CgkJRVJSKCJkc291bmQgZGllZCB3aXRob3V0IGtpbGxpbmcgdXM/XG4iKTsKCQl0aW1lS2lsbEV2ZW50KHRpbWVySUQpOwoJCXRpbWVFbmRQZXJpb2QoRFNfVElNRV9SRVMpOwoJCXJldHVybjsKCX0KCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bG9jaykpOwoKCWlmICghcHJpbWFyeWJ1ZiB8fCAhcHJpbWFyeWJ1Zi0+cmVmKSB7CgkJLyogc2VlbXMgdGhlIHByaW1hcnkgYnVmZmVyIGlzIGN1cnJlbnRseSBiZWluZyByZWxlYXNlZCAqLwoJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJcmV0dXJuOwoJfQoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDggPyAxMjggOiAwOwoKCS8qIHdoZXRoZXIgdGhlIHByaW1hcnkgaXMgZm9yY2VkIHRvIHBsYXkgZXZlbiB3aXRob3V0IHNlY29uZGFyeSBidWZmZXJzICovCglmb3JjZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoKCWlmIChwcmltYXJ5YnVmLT5od2J1ZikgewoJCWlmIChkc291bmQtPnByaW9sZXZlbCAhPSBEU1NDTF9XUklURVBSSU1BUlkpIHsKCQkJQk9PTCBwYXVzZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoJCQkvKiBGSVhNRTogZG9jdW1lbnQgdmFyaWFibGVzICovCiAJCQlEV09SRCBwbGF5cG9zLCB3cml0ZXBvcywgaW5xLCBtYXhxLCBmcmFnOwoJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKHByaW1hcnlidWYtPmh3YnVmLCAmcGxheXBvcywgJndyaXRlcG9zKTsKCQkJaWYgKGhyZXMpIHsKCQkJICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJCSAgICByZXR1cm47CgkJCX0KCQkJLyogV2VsbCwgd2UgKmNvdWxkKiBkbyBKdXN0LUluLVRpbWUgbWl4aW5nIHVzaW5nIHRoZSB3cml0ZXBvcywKCQkJICogYnV0IHRoYXQncyBhIGxpdHRsZSBiaXQgYW1iaXRpb3VzIGFuZCB1bm5lY2Vzc2FyeS4uLiAqLwoJCQkvKiByYXRoZXIgYWRkIG91ciBzYWZldHkgbWFyZ2luIHRvIHRoZSB3cml0ZXBvcywgaWYgd2UncmUgcGxheWluZyAqLwoJCQlpZiAoIXBhdXNlZCkgewoJCQkJd3JpdGVwb3MgKz0gcHJpbWFyeWJ1Zi0+d3JpdGVsZWFkOwoJCQkJd2hpbGUgKHdyaXRlcG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKCQkJCQl3cml0ZXBvcyAtPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCX0gZWxzZSB3cml0ZXBvcyA9IHBsYXlwb3M7CgkJCVRSQUNFKCJwcmltYXJ5IHBsYXlwb3M9JWxkLCB3cml0ZXBvcz0lbGQsIGNscnBvcz0lbGQsIG1peHBvcz0lbGRcbiIsCgkJCSAgICAgIHBsYXlwb3Msd3JpdGVwb3MscHJpbWFyeWJ1Zi0+cGxheXBvcyxwcmltYXJ5YnVmLT5idWZfbWl4cG9zKTsKCQkJLyogd2lwZSBvdXQganVzdC1wbGF5ZWQgc291bmQgZGF0YSAqLwoJCQlpZiAocGxheXBvcyA8IHByaW1hcnlidWYtPnBsYXlwb3MpIHsKCQkJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIgKyBwcmltYXJ5YnVmLT5wbGF5cG9zLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZsZW4gLSBwcmltYXJ5YnVmLT5wbGF5cG9zKTsKCQkJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIsIG5maWxsZXIsIHBsYXlwb3MpOwoJCQl9IGVsc2UgewoJCQkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciArIHByaW1hcnlidWYtPnBsYXlwb3MsIG5maWxsZXIsIHBsYXlwb3MgLSBwcmltYXJ5YnVmLT5wbGF5cG9zKTsKCQkJfQoJCQlwcmltYXJ5YnVmLT5wbGF5cG9zID0gcGxheXBvczsKCgkJCS8qIGNoZWNrIGhvdyBtdWNoIHByZWJ1ZmZlcmluZyBpcyBsZWZ0ICovCgkJCWlucSA9IHByaW1hcnlidWYtPmJ1Zl9taXhwb3M7CgkJCWlmIChpbnEgPCB3cml0ZXBvcykKCQkJCWlucSArPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCWlucSAtPSB3cml0ZXBvczsKCgkJCS8qIGZpbmQgdGhlIG1heGltdW0gd2UgY2FuIHByZWJ1ZmZlciAqLwoJCQlpZiAoIXBhdXNlZCkgewoJCQkJbWF4cSA9IHBsYXlwb3M7CgkJCQlpZiAobWF4cSA8IHdyaXRlcG9zKQoJCQkJCW1heHEgKz0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJCQkJbWF4cSAtPSB3cml0ZXBvczsKCQkJfSBlbHNlIG1heHEgPSBwcmltYXJ5YnVmLT5idWZsZW47CgoJCQkvKiBjbGlwIG1heHEgdG8gRFNfU05EX1FVRVVFICovCgkJCWZyYWcgPSBEU19TTkRfUVVFVUUgKiBkc291bmQtPmZyYWdsZW47CgkJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCgkJCS8qIGNoZWNrIGZvciBjb25zaXN0ZW5jeSAqLwoJCQlpZiAoaW5xID4gbWF4cSkgewoJCQkJLyogdGhlIHBsYXliYWNrIHBvc2l0aW9uIG11c3QgaGF2ZSBwYXNzZWQgb3VyIGxhc3QKCQkJCSAqIG1peGVkIHBvc2l0aW9uLCBpLmUuIGl0J3MgYW4gdW5kZXJydW4sIG9yIHdlIGhhdmUKCQkJCSAqIG5vdGhpbmcgbW9yZSB0byBwbGF5ICovCgkJCQlUUkFDRSgicmVhY2hlZCBlbmQgb2YgbWl4ZWQgZGF0YSAoaW5xPSVsZCwgbWF4cT0lbGQpXG4iLCBpbnEsIG1heHEpOwoJCQkgICAgICAgIGlucSA9IDA7CgkJCQkvKiBzdG9wIHRoZSBwbGF5YmFjayBub3csIHRvIGFsbG93IGJ1ZmZlcnMgdG8gcmVmaWxsICovCgkJCQlEU09VTkRfUHJpbWFyeVN0b3AocHJpbWFyeWJ1Zik7CgkJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgewoJCQkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJCQl9CgkJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCS8qIGhvdyBjYW4gd2UgaGF2ZSBhbiB1bmRlcnJ1biBpZiB3ZSBhcmVuJ3QgcGxheWluZz8gKi8KCQkJCQlXQVJOKCJ1bmV4cGVjdGVkIHByaW1hcnkgc3RhdGUgKCVsZClcbiIsIHByaW1hcnlidWYtPnN0YXRlKTsKCQkJCX0KCQkJCS8qIHRoZSBTdG9wIGlzIHN1cHBvc2VkIHRvIHJlc2V0IHBsYXkgcG9zaXRpb24gdG8gYmVnaW5uaW5nIG9mIGJ1ZmZlciAqLwoJCQkJLyogdW5mb3J0dW5hdGVseSwgT1NTIGlzIG5vdCBhYmxlIHRvIGRvIHNvLCBzbyBnZXQgY3VycmVudCBwb2ludGVyICovCgkJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKHByaW1hcnlidWYtPmh3YnVmLCAmcGxheXBvcywgTlVMTCk7CgkJCQlpZiAoaHJlcykgewoJCQkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQkJd3JpdGVwb3MgPSBwbGF5cG9zOwoJCQkJcHJpbWFyeWJ1Zi0+cGxheXBvcyA9IHBsYXlwb3M7CgkJCQlwcmltYXJ5YnVmLT5idWZfbWl4cG9zID0gd3JpdGVwb3M7CgkJCQlpbnEgPSAwOwoJCQkJbWF4cSA9IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgkJCQltZW1zZXQocHJpbWFyeWJ1Zi0+YnVmZmVyLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZsZW4pOwoJCQkJcGF1c2VkID0gVFJVRTsKCQkJfQoKCQkJLyogZG8gdGhlIG1peGluZyAqLwoJCQlmcmFnID0gRFNPVU5EX01peFRvUHJpbWFyeShwbGF5cG9zLCB3cml0ZXBvcywgbWF4cSwgcGF1c2VkKTsKCQkJaWYgKGZvcmNlZCkgZnJhZyA9IG1heHEgLSBpbnE7CgkJCXByaW1hcnlidWYtPmJ1Zl9taXhwb3MgKz0gZnJhZzsKCQkJd2hpbGUgKHByaW1hcnlidWYtPmJ1Zl9taXhwb3MgPj0gcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQkJcHJpbWFyeWJ1Zi0+YnVmX21peHBvcyAtPSBwcmltYXJ5YnVmLT5idWZsZW47CgoJCQlpZiAoZnJhZykgewoJCQkJLyogYnVmZmVycyBoYXZlIGJlZW4gZmlsbGVkLCByZXN0YXJ0IHBsYXliYWNrICovCgkJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJCQlEU09VTkRfUHJpbWFyeVBsYXkocHJpbWFyeWJ1Zik7CgkJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQkJCVRSQUNFKCJzdGFydGluZyBwbGF5YmFja1xuIik7CgkJCQl9CgkJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQkJLyogdGhlIHByaW1hcnlidWYgaXMgc3VwcG9zZWQgdG8gcGxheSBpZiB0aGVyZSdzIHNvbWV0aGluZyB0byBwbGF5CgkJCQkJICogZXZlbiBpZiBpdCBpcyByZXBvcnRlZCBhcyBzdG9wcGVkLCBzbyBkb24ndCBsZXQgdGhpcyBjb25mdXNlIHlvdSAqLwoJCQkJCURTT1VORF9QcmltYXJ5UGxheShwcmltYXJ5YnVmKTsKCQkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJCQkJCVRSQUNFKCJzdGFydGluZyBwbGF5YmFja1xuIik7CgkJCQl9CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJfSBlbHNlIHsKCQkJLyogaW4gdGhlIERTU0NMX1dSSVRFUFJJTUFSWSBtb2RlLCB0aGUgYXBwIGlzIHRvdGFsbHkgaW4gY2hhcmdlLi4uICovCgkJCWlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgewoJCQkJRFNPVU5EX1ByaW1hcnlQbGF5KHByaW1hcnlidWYpOwoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQl9IAoJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJRFNPVU5EX1ByaW1hcnlTdG9wKHByaW1hcnlidWYpOwoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJfQoJfSBlbHNlIHsKCQkvKiB1c2luZyB3YXZlT3V0IHN0dWZmICovCgkJLyogaWYgbm8gYnVmZmVycyBhcmUgcGxheWluZywgd2Ugc2hvdWxkIGJlIGluIHBhdXNlIG1vZGUgbm93ICovCgkJRFdPUkQgd3JpdGVwb3MsIG1peHE7CgkJLyogY2xlYW4gb3V0IGNvbXBsZXRlZCBmcmFnbWVudHMgKi8KCQl3aGlsZSAoZHNvdW5kLT5wd3F1ZXVlICYmIChkc291bmQtPnB3YXZlW2Rzb3VuZC0+cHdwbGF5XS0+ZHdGbGFncyAmIFdIRFJfRE9ORSkpIHsKCQkJaWYgKGRzb3VuZC0+cHJpb2xldmVsICE9IERTU0NMX1dSSVRFUFJJTUFSWSkgewoJCQkJRFdPUkQgcG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CgkJCQlUUkFDRSgiZG9uZSBwbGF5aW5nIHByaW1hcnkgcG9zPSVsZFxuIixwb3MpOwoJCQkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciArIHBvcywgbmZpbGxlciwgZHNvdW5kLT5mcmFnbGVuKTsKCQkJfQoJCQlkc291bmQtPnB3cGxheSsrOwoJCQlpZiAoZHNvdW5kLT5wd3BsYXkgPj0gRFNfSEVMX0ZSQUdTKSBkc291bmQtPnB3cGxheSA9IDA7CgkJCWRzb3VuZC0+cHdxdWV1ZS0tOwoJCX0KCQlwcmltYXJ5YnVmLT5wbGF5cG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CgkJVFJBQ0UoInByaW1hcnkgcGxheXBvcz0lbGQsIG1peHBvcz0lbGRcbiIscHJpbWFyeWJ1Zi0+cGxheXBvcyxwcmltYXJ5YnVmLT5idWZfbWl4cG9zKTsKCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCgkJaWYgKCFkc291bmQtPnB3cXVldWUpIHsKCQkJLyogdGhpcyBpcyBlaXRoZXIgYW4gdW5kZXJydW4gb3Igd2UgaGF2ZSBub3RoaW5nIG1vcmUgdG8gcGxheS4uLgoJCQkgKiBzaW5jZSBwbGF5YmFjayBoYXMgYWxyZWFkeSBzdG9wcGVkIG5vdywgd2UgY2FuIGVudGVyIHBhdXNlIG1vZGUsCgkJCSAqIGluIG9yZGVyIHRvIGFsbG93IGJ1ZmZlcnMgdG8gcmVmaWxsICovCgkJCWlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB7CgkJCQlUUkFDRSgibm8gbW9yZSBmcmFnbWVudHMgcmVhZHkgdG8gcGxheVxuIik7CgkJCQl3YXZlT3V0UGF1c2UoZHNvdW5kLT5od28pOwoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJfQoJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJVFJBQ0UoIm5vIG1vcmUgZnJhZ21lbnRzIHJlYWR5IHRvIHBsYXlcbiIpOwoJCQkJd2F2ZU91dFBhdXNlKGRzb3VuZC0+aHdvKTsKCQkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJfQoJCX0KCgkJLyogZmluZCBuZXh0IHdyaXRlIHBvc2l0aW9uLCBwbHVzIHNvbWUgZXh0cmEgbWFyZ2luLCBpZiBuZWNlc3NhcnkgKi8KCQltaXhxID0gRFNfSEVMX01BUkdJTjsKCQlpZiAobWl4cSA+IGRzb3VuZC0+cHdxdWV1ZSkgbWl4cSA9IGRzb3VuZC0+cHdxdWV1ZTsKCQl3cml0ZXBvcyA9IHByaW1hcnlidWYtPnBsYXlwb3MgKyBtaXhxICogZHNvdW5kLT5mcmFnbGVuOwoJCXdoaWxlICh3cml0ZXBvcyA+PSBwcmltYXJ5YnVmLT5idWZsZW4pIHdyaXRlcG9zIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCgkJLyogZG8gdGhlIG1peGluZyAqLwoJCWlmIChkc291bmQtPnByaW9sZXZlbCAhPSBEU1NDTF9XUklURVBSSU1BUlkpIHsKCQkJRFdPUkQgZnJhZywgbWF4cSA9IERTX1NORF9RVUVVRSAqIGRzb3VuZC0+ZnJhZ2xlbjsKCQkJZnJhZyA9IERTT1VORF9NaXhUb1ByaW1hcnkocHJpbWFyeWJ1Zi0+cGxheXBvcywgd3JpdGVwb3MsIG1heHEsIEZBTFNFKTsKCQkJbWl4cSA9IGZyYWcgLyBkc291bmQtPmZyYWdsZW47CgkJCWlmIChmcmFnIC0gKG1peHEgKiBkc291bmQtPmZyYWdsZW4pKQoJCQkJbWl4cSsrOwoJCX0gZWxzZSBtaXhxID0gMDsKCQlpZiAoZm9yY2VkKSBtaXhxID0gRFNfU05EX1FVRVVFOwoKCQkvKiBvdXRwdXQgaXQgKi8KCQlmb3IgKDsgbWl4cTsgbWl4cS0tKSB7CgkJCXdhdmVPdXRXcml0ZShkc291bmQtPmh3bywgZHNvdW5kLT5wd2F2ZVtkc291bmQtPnB3d3JpdGVdLCBzaXplb2YoV0FWRUhEUikpOwoJCQlkc291bmQtPnB3d3JpdGUrKzsKCQkJaWYgKGRzb3VuZC0+cHd3cml0ZSA+PSBEU19IRUxfRlJBR1MpIGRzb3VuZC0+cHd3cml0ZSA9IDA7CgkJCWRzb3VuZC0+cHdxdWV1ZSsrOwoJCX0KCQlwcmltYXJ5YnVmLT5idWZfbWl4cG9zID0gZHNvdW5kLT5wd3dyaXRlICogZHNvdW5kLT5mcmFnbGVuOwoKCQlpZiAoZHNvdW5kLT5wd3F1ZXVlKSB7CgkJCS8qIGJ1ZmZlcnMgaGF2ZSBiZWVuIGZpbGxlZCwgcmVzdGFydCBwbGF5YmFjayAqLwoJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJCXdhdmVPdXRSZXN0YXJ0KGRzb3VuZC0+aHdvKTsKCQkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCQkJCVRSQUNFKCJzdGFydGluZyBwbGF5YmFja1xuIik7CgkJCX0KCQkJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCQkJLyogdGhlIHByaW1hcnlidWYgaXMgc3VwcG9zZWQgdG8gcGxheSBpZiB0aGVyZSdzIHNvbWV0aGluZyB0byBwbGF5CgkJCQkgKiBldmVuIGlmIGl0IGlzIHJlcG9ydGVkIGFzIHN0b3BwZWQsIHNvIGRvbid0IGxldCB0aGlzIGNvbmZ1c2UgeW91ICovCgkJCQl3YXZlT3V0UmVzdGFydChkc291bmQtPmh3byk7CgkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJCQkJVFJBQ0UoInN0YXJ0aW5nIHBsYXliYWNrXG4iKTsKCQkJfQoJCX0KCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCX0KCVRSQUNFKCJjb21wbGV0ZWQgcHJvY2Vzc2luZ1xuIik7CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bG9jaykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGlyZWN0U291bmRDcmVhdGUgKERTT1VORC4xKQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRDcmVhdGUoUkVGR1VJRCBscEdVSUQsTFBESVJFQ1RTT1VORCAqcHBEUyxJVW5rbm93biAqcFVua091dGVyICkKewoJSURpcmVjdFNvdW5kSW1wbCoqIGlwcERTPShJRGlyZWN0U291bmRJbXBsKiopcHBEUzsKCVBJRFNEUklWRVIgZHJ2ID0gTlVMTDsKCVdBVkVPVVRDQVBTQSB3Y2FwczsKCXVuc2lnbmVkIHdvZCwgd29kbjsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CgoJaWYgKGxwR1VJRCkKCQlUUkFDRSgiKCVwLCVwLCVwKVxuIixscEdVSUQsaXBwRFMscFVua091dGVyKTsKCWVsc2UKCQlUUkFDRSgiRGlyZWN0U291bmRDcmVhdGUgKCVwKVxuIiwgaXBwRFMpOwoKCWlmIChpcHBEUyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJaWYgKHByaW1hcnlidWYpIHsKCQlJRGlyZWN0U291bmRfQWRkUmVmKChMUERJUkVDVFNPVU5EKWRzb3VuZCk7CgkJKmlwcERTID0gZHNvdW5kOwoJCXJldHVybiBEU19PSzsKCX0KCgkvKiBFbnVtZXJhdGUgV0lOTU0gYXVkaW8gZGV2aWNlcyBhbmQgZmluZCB0aGUgb25lIHdlIHdhbnQgKi8KCXdvZG4gPSB3YXZlT3V0R2V0TnVtRGV2cygpOwoJaWYgKCF3b2RuKSByZXR1cm4gRFNFUlJfTk9EUklWRVI7CgoJLyogRklYTUU6IEhvdyBkbyB3ZSBmaW5kIHRoZSBHVUlEIG9mIGFuIGF1ZGlvIGRldmljZT8gKi8KCS8qIFdlbGwsIGp1c3QgdXNlIHRoZSBmaXJzdCBhdmFpbGFibGUgZGV2aWNlIGZvciBub3cuLi4gKi8KCXdvZCA9IDA7CgkvKiBHZXQgb3V0cHV0IGRldmljZSBjYXBzICovCgl3YXZlT3V0R2V0RGV2Q2Fwc0Eod29kLCAmd2NhcHMsIHNpemVvZih3Y2FwcykpOwoJLyogRFJWX1FVRVJZRFNPVU5ESUZBQ0UgaXMgYSAiV2luZSBleHRlbnNpb24iIHRvIGdldCB0aGUgRFNvdW5kIGludGVyZmFjZSAqLwoJd2F2ZU91dE1lc3NhZ2Uod29kLCBEUlZfUVVFUllEU09VTkRJRkFDRSwgKERXT1JEKSZkcnYsIDApOwoKCS8qIEFsbG9jYXRlIG1lbW9yeSAqLwoJKmlwcERTID0gKElEaXJlY3RTb3VuZEltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKElEaXJlY3RTb3VuZEltcGwpKTsKCWlmICgqaXBwRFMgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgoJSUNPTV9WVEJMKCppcHBEUykJPSAmZHN2dDsKCSgqaXBwRFMpLT5yZWYJCT0gMTsKCgkoKmlwcERTKS0+ZHJpdmVyCT0gZHJ2OwoJKCppcHBEUyktPmZyYWdsZW4JPSAwOwoJKCppcHBEUyktPnByaW9sZXZlbAk9IERTU0NMX05PUk1BTDsgCgkoKmlwcERTKS0+bnJvZmJ1ZmZlcnMJPSAwOwoJKCppcHBEUyktPmJ1ZmZlcnMJPSBOVUxMOwoJKCppcHBEUyktPnByaW1hcnkJPSBOVUxMOyAKCSgqaXBwRFMpLT5saXN0ZW5lcgk9IE5VTEw7IAoKCS8qIEdldCBkcml2ZXIgZGVzY3JpcHRpb24gKi8KCWlmIChkcnYpIHsKCQlJRHNEcml2ZXJfR2V0RHJpdmVyRGVzYyhkcnYsJigoKmlwcERTKS0+ZHJ2ZGVzYykpOwoJfSBlbHNlIHsKCQkvKiBpZiBubyBEaXJlY3RTb3VuZCBpbnRlcmZhY2UgYXZhaWxhYmxlLCB1c2UgV0lOTU0gQVBJIGluc3RlYWQgKi8KCQkoKmlwcERTKS0+ZHJ2ZGVzYy5kd0ZsYWdzID0gRFNEREVTQ19ET01NU1lTVEVNT1BFTiB8IERTRERFU0NfRE9NTVNZU1RFTVNFVEZPUk1BVDsKCQkoKmlwcERTKS0+ZHJ2ZGVzYy5kbkRldk5vZGUgPSB3b2Q7IC8qIEZJWE1FPyAqLwoJfQoKCS8qIFNldCBkZWZhdWx0IHdhdmUgZm9ybWF0IChtYXkgbmVlZCBpdCBmb3Igd2F2ZU91dE9wZW4pICovCgkoKmlwcERTKS0+d2Z4LndGb3JtYXRUYWcJPSBXQVZFX0ZPUk1BVF9QQ007CgkoKmlwcERTKS0+d2Z4Lm5DaGFubmVscwkJPSAyOwoJKCppcHBEUyktPndmeC5uU2FtcGxlc1BlclNlYwk9IDIyMDUwOwoJKCppcHBEUyktPndmeC5uQXZnQnl0ZXNQZXJTZWMJPSA0NDEwMDsKCSgqaXBwRFMpLT53ZngubkJsb2NrQWxpZ24JPSAyOwoJKCppcHBEUyktPndmeC53Qml0c1BlclNhbXBsZQk9IDg7CgoJLyogSWYgdGhlIGRyaXZlciByZXF1ZXN0cyBiZWluZyBvcGVuZWQgdGhyb3VnaCBNTVNZU1RFTQoJICogKHdoaWNoIGlzIHJlY29tbWVuZGVkIGJ5IHRoZSBEREspLCBpdCBpcyBzdXBwb3NlZCB0byBoYXBwZW4KCSAqIGJlZm9yZSB0aGUgRGlyZWN0U291bmQgaW50ZXJmYWNlIGlzIG9wZW5lZCAqLwoJaWYgKCgqaXBwRFMpLT5kcnZkZXNjLmR3RmxhZ3MgJiBEU0RERVNDX0RPTU1TWVNURU1PUEVOKSB7CgkJLyogRklYTUU6IGlzIHRoaXMgcmlnaHQ/ICovCgkJZXJyID0gbW1FcnIod2F2ZU91dE9wZW4oJigoKmlwcERTKS0+aHdvKSwgKCppcHBEUyktPmRydmRlc2MuZG5EZXZOb2RlLCAmKCgqaXBwRFMpLT53ZngpLAoJCQkJCTAsIDAsIENBTExCQUNLX05VTEwgfCBXQVZFX0RJUkVDVFNPVU5EKSk7Cgl9CgoJaWYgKGRydiAmJiAoZXJyID09IERTX09LKSkKCQllcnIgPSBJRHNEcml2ZXJfT3BlbihkcnYpOwoKCS8qIEZJWE1FOiBkbyB3ZSB3YW50IHRvIGhhbmRsZSBhIHRlbXBvcmFyaWx5IGJ1c3kgZGV2aWNlPyAqLwoJaWYgKGVyciAhPSBEU19PSykgewoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCwqaXBwRFMpOwoJCSppcHBEUyA9IE5VTEw7CgkJcmV0dXJuIGVycjsKCX0KCgkvKiB0aGUgZHJpdmVyIGlzIG5vdyBvcGVuLCBzbyBpdCdzIG5vdyBhbGxvd2VkIHRvIGNhbGwgR2V0Q2FwcyAqLwoJaWYgKGRydikgewoJCUlEc0RyaXZlcl9HZXRDYXBzKGRydiwmKCgqaXBwRFMpLT5kcnZjYXBzKSk7Cgl9IGVsc2UgewoJCXVuc2lnbmVkIGM7CgoJCS8qIEZJWE1FOiBsb29rIGF0IHdjYXBzICovCgkJKCppcHBEUyktPmRydmNhcHMuZHdGbGFncyA9CgkJCURTQ0FQU19QUklNQVJZMTZCSVQgfCBEU0NBUFNfUFJJTUFSWVNURVJFTzsKCQlpZiAoRFNfRU1VTERSSVZFUikKCQkgICAgKCppcHBEUyktPmRydmNhcHMuZHdGbGFncyB8PSBEU0NBUFNfRU1VTERSSVZFUjsKCgkJLyogQWxsb2NhdGUgbWVtb3J5IGZvciBIRUwgYnVmZmVyIGhlYWRlcnMgKi8KCQlmb3IgKGM9MDsgYzxEU19IRUxfRlJBR1M7IGMrKykgewoJCQkoKmlwcERTKS0+cHdhdmVbY10gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihXQVZFSERSKSk7CgkJCWlmICghKCppcHBEUyktPnB3YXZlW2NdKSB7CgkJCQkvKiBBcmdoLCBvdXQgb2YgbWVtb3J5ICovCgkJCQl3aGlsZSAoYy0tKSB7CgkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCgqaXBwRFMpLT5wd2F2ZVtjXSk7CgkJCQkJd2F2ZU91dENsb3NlKCgqaXBwRFMpLT5od28pOwoJCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCwqaXBwRFMpOwoJCQkJCSppcHBEUyA9IE5VTEw7CgkJCQkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJCQkJfQoJCQl9CgkJfQoJfQoKCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJigoKmlwcERTKS0+bG9jaykpOwoKCWlmICghZHNvdW5kKSB7CgkJZHNvdW5kID0gKCppcHBEUyk7CgkJaWYgKHByaW1hcnlidWYgPT0gTlVMTCkgewoJCQlEU0JVRkZFUkRFU0MJZHNiZDsKCQkJSFJFU1VMVAkJaHI7CgoJCQlkc2JkLmR3U2l6ZSA9IHNpemVvZihEU0JVRkZFUkRFU0MpOwoJCQlkc2JkLmR3RmxhZ3MgPSBEU0JDQVBTX1BSSU1BUllCVUZGRVI7CgkJCWRzYmQuZHdCdWZmZXJCeXRlcyA9IDA7CgkJCWRzYmQubHB3ZnhGb3JtYXQgPSAmKGRzb3VuZC0+d2Z4KTsKCQkJaHIgPSBJRGlyZWN0U291bmRfQ3JlYXRlU291bmRCdWZmZXIoKnBwRFMsICZkc2JkLCAoTFBESVJFQ1RTT1VOREJVRkZFUiopJnByaW1hcnlidWYsIE5VTEwpOwoJCQlpZiAoaHIgIT0gRFNfT0spCgkJCQlyZXR1cm4gaHI7CgoJCQkvKiBkc291bmQtPnByaW1hcnkgaXMgTlVMTCAtIGRvbid0IG5lZWQgdG8gUmVsZWFzZSAqLwoJCQlkc291bmQtPnByaW1hcnkgPSBwcmltYXJ5YnVmOwoJCQlJRGlyZWN0U291bmRCdWZmZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EQlVGRkVSKXByaW1hcnlidWYpOwoJCX0KCQl0aW1lQmVnaW5QZXJpb2QoRFNfVElNRV9SRVMpOwoJCWRzb3VuZC0+dGltZXJJRCA9IHRpbWVTZXRFdmVudChEU19USU1FX0RFTCwgRFNfVElNRV9SRVMsIERTT1VORF90aW1lciwKCQkJCQkgICAgICAgKERXT1JEKWRzb3VuZCwgVElNRV9QRVJJT0RJQyB8IFRJTUVfQ0FMTEJBQ0tfRlVOQ1RJT04pOwoJfQoJcmV0dXJuIERTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kQ2FwdHVyZUNyZWF0ZSBbRFNPVU5ELjZdCiAqCiAqIENyZWF0ZSBhbmQgaW5pdGlhbGl6ZSBhIERpcmVjdFNvdW5kQ2FwdHVyZSBpbnRlcmZhY2UKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9OT0FHR1JFR0FUSU9OLCBEU0VSUl9BTExPQ0FURUQsIERTRVJSX0lOVkFMSURQQVJBTSwKICogICAgICAgICAgICAgRFNFUlJfT1VUT0ZNRU1PUlkKICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kQ2FwdHVyZUNyZWF0ZSgKCUxQQ0dVSUQgbHBjR1VJRCwKCUxQRElSRUNUU09VTkRDQVBUVVJFKiBscGxwRFNDLAoJTFBVTktOT1dOIHBVbmtPdXRlciApCnsKCVRSQUNFKCIoJXMsJXAsJXApXG4iLCBkZWJ1Z3N0cl9ndWlkKGxwY0dVSUQpLCBscGxwRFNDLCBwVW5rT3V0ZXIpOwoKCWlmKCBwVW5rT3V0ZXIgKSB7CgkJcmV0dXJuIERTRVJSX05PQUdHUkVHQVRJT047Cgl9CgoJLyogRGVmYXVsdCBkZXZpY2U/ICovCglpZiAoICFscGNHVUlEICkgewoJCXJldHVybiBEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlKCAoTFBWT0lEKilscGxwRFNDICk7Cgl9CgoJRklYTUUoICJVbmtub3duIEdVSUQgJXNcbiIsIGRlYnVnc3RyX2d1aWQobHBjR1VJRCkgKTsKCSpscGxwRFNDID0gTlVMTDsKCglyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlQSBbRFNPVU5ELjddCiAqCiAqIEVudW1lcmF0ZSBhbGwgRGlyZWN0U291bmQgZHJpdmVycyBpbnN0YWxsZWQgaW4gdGhlIHN5c3RlbQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERTX09LCiAqICAgIEZhaWx1cmU6IERTRVJSX0lOVkFMSURQQVJBTQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlQSgKICAgICAgICBMUERTRU5VTUNBTExCQUNLQSBscERTRW51bUNhbGxiYWNrLAogICAgICAgIExQVk9JRCBscENvbnRleHQpCnsKCVRSQUNFKCIoJXAsJXApXG4iLCBscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQgKTsKCglpZiAoIGxwRFNFbnVtQ2FsbGJhY2sgKQoJCWxwRFNFbnVtQ2FsbGJhY2soTlVMTCwiV0lORSBQcmltYXJ5IFNvdW5kIENhcHR1cmUgRHJpdmVyIiwKICAgICAgICAgICAgICAgICAgICAiU291bmRDYXAiLGxwQ29udGV4dCk7CgoKCXJldHVybiBEU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZENhcHR1cmVFbnVtZXJhdGVXIFtEU09VTkQuOF0KICoKICogRW51bWVyYXRlIGFsbCBEaXJlY3RTb3VuZCBkcml2ZXJzIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfSU5WQUxJRFBBUkFNCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENhcHR1cmVFbnVtZXJhdGVXKAogICAgICAgIExQRFNFTlVNQ0FMTEJBQ0tXIGxwRFNFbnVtQ2FsbGJhY2ssCiAgICAgICAgTFBWT0lEIGxwQ29udGV4dCkKewogICAgICAgIEZJWE1FKCIoJXAsJXApOnN0dWJcbiIsIGxwRFNFbnVtQ2FsbGJhY2ssIGxwQ29udGV4dCApOwogICAgICAgIHJldHVybiBEU19PSzsKfSAKCnN0YXRpYyBIUkVTVUxUCkRTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmUoIExQVk9JRCogcHBvYmogKQp7CgkqcHBvYmogPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZiggSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwgKSApOwoKCWlmICggKnBwb2JqID09IE5VTEwgKSB7CgkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJfQoKCXsKCQlJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsKnBwb2JqKTsKCgkJVGhpcy0+cmVmID0gMTsKCQlJQ09NX1ZUQkwoVGhpcykgPSAmZHNjdnQ7CgoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7Cgl9CgoJcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlLAoJUkVGSUlEIHJpaWQsCglMUFZPSUQqIHBwb2JqICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcywlcCk6IHN0dWJcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwb2JqICk7CgoJcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9BZGRSZWYoIExQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlICkKewoJVUxPTkcgdVJlZjsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKCVRSQUNFKCAiKCVwKSB3YXMgMHglMDhseFxuIiwgVGhpcywgVGhpcy0+cmVmICk7Cgl1UmVmID0gKysoVGhpcy0+cmVmKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCiAgICAgICAgcmV0dXJuIHVSZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfUmVsZWFzZSggTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UgKQp7CglVTE9ORyB1UmVmOwoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwoJdVJlZiA9IC0tKFRoaXMtPnJlZik7CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJaWYgKCB1UmVmID09IDAgKSB7CgkJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoJCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzICk7Cgl9CgoJcmV0dXJuIHVSZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9DcmVhdGVDYXB0dXJlQnVmZmVyKAoJTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UsCglMUENEU0NCVUZGRVJERVNDIGxwY0RTQ0J1ZmZlckRlc2MsCglMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiogbHBscERTQ2FwdHVyZUJ1ZmZlciwgCglMUFVOS05PV04gcFVuayApCnsKCUhSRVNVTFQgaHI7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKCVRSQUNFKCAiKCVwKS0+KCVwLCVwLCVwKVxuIiwgVGhpcywgbHBjRFNDQnVmZmVyRGVzYywgbHBscERTQ2FwdHVyZUJ1ZmZlciwgcFVuayApOwoKCWlmICggcFVuayApIHsKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJfQoKCWhyID0gRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlciggbHBjRFNDQnVmZmVyRGVzYywgKExQVk9JRCopbHBscERTQ2FwdHVyZUJ1ZmZlciApOwoKCXJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0dldENhcHMoCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSwKCUxQRFNDQ0FQUyBscERTQ0NhcHMgKQp7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCiAgICAgICAgRklYTUUoICIoJXApLT4oJXApOiBzdHViXG4iLCBUaGlzLCBscERTQ0NhcHMgKTsKCiAgICAgICAgcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfSW5pdGlhbGl6ZSgKCUxQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlLAoJTFBDR1VJRCBscGNHVUlEICkKewogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgogICAgICAgIEZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBjR1VJRCApOwoKICAgICAgICByZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZSkgZHNjdnQgPQp7CiAgICAgICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgICAgICAvKiBJVW5rbm93biBtZXRob2RzICovCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfQWRkUmVmLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX1JlbGVhc2UsCgogICAgICAgIC8qIElEaXJlY3RTb3VuZENhcHR1cmUgbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0NyZWF0ZUNhcHR1cmVCdWZmZXIsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfR2V0Q2FwcywKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9Jbml0aWFsaXplIAp9OwoKc3RhdGljIEhSRVNVTFQKRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlciggTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCdWZmZXJEZXNjLCBMUFZPSUQqIHBwb2JqICkKewoKCUZJWE1FKCAiKCVwLCVwKTogaWdub3JpbmcgbHBjRFNDQnVmZmVyRGVzY1xuIiwgbHBjRFNDQnVmZmVyRGVzYywgcHBvYmogKTsKCgkqcHBvYmogPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZiggSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwgKSApOwoKCWlmICggKnBwb2JqID09IE5VTEwgKSB7CgkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJfQoKCXsKCQlJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsKnBwb2JqKTsKCgkJVGhpcy0+cmVmID0gMTsKCQlJQ09NX1ZUQkwoVGhpcykgPSAmZHNjYnZ0OwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoJfQoKCXJldHVybiBTX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAogICAgICAgIFJFRklJRCByaWlkLAogICAgICAgIExQVk9JRCogcHBvYmogKQp7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCiAgICAgICAgRklYTUUoICIoJXApLT4oJXMsJXApOiBzdHViXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcG9iaiApOwoKICAgICAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0FkZFJlZiggTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UgKQp7CiAgICAgICAgVUxPTkcgdVJlZjsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwogICAgICAgIHVSZWYgPSArKyhUaGlzLT5yZWYpOwoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCiAgICAgICAgcmV0dXJuIHVSZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfUmVsZWFzZSggTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UgKQp7CiAgICAgICAgVUxPTkcgdVJlZjsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwogICAgICAgIHVSZWYgPSAtLShUaGlzLT5yZWYpOwoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCiAgICAgICAgaWYgKCB1UmVmID09IDAgKSB7CgkJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMgKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB1UmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Q2FwcygKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQRFNDQkNBUFMgbHBEU0NCQ2FwcyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXApOiBzdHViXG4iLCBUaGlzLCBscERTQ0JDYXBzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBEV09SRCBscGR3Q2FwdHVyZVBvc2l0aW9uLAoJTFBEV09SRCBscGR3UmVhZFBvc2l0aW9uICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCwlcCk6IHN0dWJcbiIsIFRoaXMsIGxwZHdDYXB0dXJlUG9zaXRpb24sIGxwZHdSZWFkUG9zaXRpb24gKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRGb3JtYXQoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUFdBVkVGT1JNQVRFWCBscHdmeEZvcm1hdCwgCglEV09SRCBkd1NpemVBbGxvY2F0ZWQsIAoJTFBEV09SRCBscGR3U2l6ZVdyaXR0ZW4gKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwLDB4JTA4bHgsJXApOiBzdHViXG4iLCBUaGlzLCBscHdmeEZvcm1hdCwgZHdTaXplQWxsb2NhdGVkLCBscGR3U2l6ZVdyaXR0ZW4gKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRTdGF0dXMoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUERXT1JEIGxwZHdTdGF0dXMgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBkd1N0YXR1cyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0luaXRpYWxpemUoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBscERTQywgCglMUENEU0NCVUZGRVJERVNDIGxwY0RTQ0JEZXNjICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCwlcCk6IHN0dWJcbiIsIFRoaXMsIGxwRFNDLCBscGNEU0NCRGVzYyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0xvY2soCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglEV09SRCBkd1JlYWRDdXNvciwgCglEV09SRCBkd1JlYWRCeXRlcywgCglMUFZPSUQqIGxwbHB2QXVkaW9QdHIxLCAKCUxQRFdPUkQgbHBkd0F1ZGlvQnl0ZXMxLCAKCUxQVk9JRCogbHBscHZBdWRpb1B0cjIsIAoJTFBEV09SRCBscGR3QXVkaW9CeXRlczIsIAoJRFdPUkQgZHdGbGFncyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJTA4bHUsJTA4bHUsJXAsJXAsJXAsJXAsMHglMDhseCk6IHN0dWJcbiIsIFRoaXMsIGR3UmVhZEN1c29yLCBkd1JlYWRCeXRlcywgbHBscHZBdWRpb1B0cjEsIGxwZHdBdWRpb0J5dGVzMSwgbHBscHZBdWRpb1B0cjIsIGxwZHdBdWRpb0J5dGVzMiwgZHdGbGFncyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1N0YXJ0KAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJRFdPUkQgZHdGbGFncyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oMHglMDhseCk6IHN0dWJcbiIsIFRoaXMsIGR3RmxhZ3MgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdG9wKCBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApOiBzdHViXG4iLCBUaGlzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfVW5sb2NrKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBWT0lEIGxwdkF1ZGlvUHRyMSwgCglEV09SRCBkd0F1ZGlvQnl0ZXMxLCAKCUxQVk9JRCBscHZBdWRpb1B0cjIsIAoJRFdPUkQgZHdBdWRpb0J5dGVzMiApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXAsJTA4bHUsJXAsJTA4bHUpOiBzdHViXG4iLCBUaGlzLCBscHZBdWRpb1B0cjEsIGR3QXVkaW9CeXRlczEsIGxwdkF1ZGlvUHRyMiwgZHdBdWRpb0J5dGVzMiApOwoKCXJldHVybiBEU19PSzsKfQoKCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKSBkc2NidnQgPQp7CiAgICAgICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgICAgICAvKiBJVW5rbm93biBtZXRob2RzICovCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfQWRkUmVmLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1JlbGVhc2UsCgogICAgICAgIC8qIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIgbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldENhcHMsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldEZvcm1hdCwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRTdGF0dXMsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfSW5pdGlhbGl6ZSwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9Mb2NrLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1N0YXJ0LAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1N0b3AsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfVW5sb2NrCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZCBDbGFzc0ZhY3RvcnkKICovCnR5cGVkZWYgc3RydWN0CnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSUNsYXNzRmFjdG9yeSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgcmVmOwp9IElDbGFzc0ZhY3RvcnlJbXBsOwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIApEU0NGX1F1ZXJ5SW50ZXJmYWNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCktPiglcywlcCksc3R1YiFcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCkRTQ0ZfQWRkUmVmKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgRFNDRl9SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJLyogc3RhdGljIGNsYXNzLCB3b24ndCBiZSAgZnJlZWQgKi8KCXJldHVybiAtLShUaGlzLT5yZWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgRFNDRl9DcmVhdGVJbnN0YW5jZSgKCUxQQ0xBU1NGQUNUT1JZIGlmYWNlLExQVU5LTk9XTiBwT3V0ZXIsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iagopIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCktPiglcCwlcywlcClcbiIsVGhpcyxwT3V0ZXIsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZCwgcmlpZCApICkgewoJCS8qIEZJWE1FOiByZXVzZSBhbHJlYWR5IGNyZWF0ZWQgZHNvdW5kIGlmIHByZXNlbnQ/ICovCgkJcmV0dXJuIERpcmVjdFNvdW5kQ3JlYXRlKHJpaWQsKExQRElSRUNUU09VTkQqKXBwb2JqLHBPdXRlcik7Cgl9CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIERTQ0ZfTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSxCT09MIGRvbG9jaykgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCUZJWE1FKCIoJXApLT4oJWQpLHN0dWIhXG4iLFRoaXMsZG9sb2NrKTsKCXJldHVybiBTX09LOwp9CgpzdGF0aWMgSUNPTV9WVEFCTEUoSUNsYXNzRmFjdG9yeSkgRFNDRl9WdGJsID0gewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCURTQ0ZfUXVlcnlJbnRlcmZhY2UsCglEU0NGX0FkZFJlZiwKCURTQ0ZfUmVsZWFzZSwKCURTQ0ZfQ3JlYXRlSW5zdGFuY2UsCglEU0NGX0xvY2tTZXJ2ZXIKfTsKc3RhdGljIElDbGFzc0ZhY3RvcnlJbXBsIERTT1VORF9DRiA9IHsmRFNDRl9WdGJsLCAxIH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxHZXRDbGFzc09iamVjdCBbRFNPVU5ELjVdCiAqIFJldHJpZXZlcyBjbGFzcyBvYmplY3QgZnJvbSBhIERMTCBvYmplY3QKICoKICogTk9URVMKICogICAgRG9jcyBzYXkgcmV0dXJucyBTVERBUEkKICoKICogUEFSQU1TCiAqICAgIHJjbHNpZCBbSV0gQ0xTSUQgZm9yIHRoZSBjbGFzcyBvYmplY3QKICogICAgcmlpZCAgIFtJXSBSZWZlcmVuY2UgdG8gaWRlbnRpZmllciBvZiBpbnRlcmZhY2UgZm9yIGNsYXNzIG9iamVjdAogKiAgICBwcHYgICAgW09dIEFkZHJlc3Mgb2YgdmFyaWFibGUgdG8gcmVjZWl2ZSBpbnRlcmZhY2UgcG9pbnRlciBmb3IgcmlpZAogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRSwgRV9PVVRPRk1FTU9SWSwgRV9JTlZBTElEQVJHLAogKiAgICAgICAgICAgICBFX1VORVhQRUNURUQKICovCkRXT1JEIFdJTkFQSSBEU09VTkRfRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLFJFRklJRCByaWlkLExQVk9JRCAqcHB2KQp7CiAgICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwogICAgaWYgKCBJc0VxdWFsQ0xTSUQoICZJSURfSUNsYXNzRmFjdG9yeSwgcmlpZCApICkgewogICAgCSpwcHYgPSAoTFBWT0lEKSZEU09VTkRfQ0Y7CglJQ2xhc3NGYWN0b3J5X0FkZFJlZigoSUNsYXNzRmFjdG9yeSopKnBwdik7CiAgICByZXR1cm4gU19PSzsKICAgIH0KCiAgICBGSVhNRSgiKCVwLCVwLCVwKTogbm8gaW50ZXJmYWNlIGZvdW5kLlxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwogICAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxDYW5VbmxvYWROb3cgW0RTT1VORC40XSAgRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBETEwgaXMgaW4gdXNlLgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogU19GQUxTRQogKi8KRFdPUkQgV0lOQVBJIERTT1VORF9EbGxDYW5VbmxvYWROb3codm9pZCkKewogICAgRklYTUUoIih2b2lkKTogc3R1YlxuIik7CiAgICByZXR1cm4gU19GQUxTRTsKfQo=