LyoKICogdGFibGUuYyAKICovCgovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3RhYmxlLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfYXNzZXJ0Lmg+CgpzdGF0aWMgdm9pZCAgICAgdGFibGVfaGVscGVyX2NsZWFudXAobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGF0dXMpOwpzdGF0aWMgdm9pZCAgICAgdGFibGVfZGF0YV9mcmVlX2Z1bmModm9pZCAqZGF0YSk7CnN0YXRpYyBpbnQKc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpOwoKLyoqIEBkZWZncm91cCB0YWJsZSB0YWJsZQogKiAgSGVscHMgeW91IGltcGxlbWVudCBhIHRhYmxlLgogKiAgQGluZ3JvdXAgaGFuZGxlcgogKgogKiAgVGhpcyBoYW5kbGVyIGhlbHBzIHlvdSBpbXBsZW1lbnQgYSB0YWJsZSBieSBkb2luZyBzb21lIG9mIHRoZQogKiAgcHJvY2Vzc2luZyBmb3IgeW91LgogKiAgCiAqICBUaGlzIGhhbmRsZXIgdHJ1bHkgc2hvd3MgdGhlIHBvd2VyIG9mIHRoZSBuZXcgaGFuZGxlciBtZWNoYW5pc20uCiAqICBCeSBjcmVhdGluZyBhIHRhYmxlIGhhbmRsZXIgYW5kIGluamVjdGluZyBpdCBpbnRvIHlvdXIgY2FsbGluZwogKiAgY2hhaW4sIG9yIGJ5IHVzaW5nIHRoZSBuZXRzbm1wX3JlZ2lzdGVyX3RhYmxlKCkgZnVuY3Rpb24gdG8gcmVnaXN0ZXIgeW91cgogKiAgdGFibGUsIHlvdSBnZXQgYWNjZXNzIHRvIHNvbWUgcHJlLXBhcnNlZCBpbmZvcm1hdGlvbi4KICogIFNwZWNpZmljYWxseSwgdGhlIHRhYmxlIGhhbmRsZXIgcHVsbHMgb3V0IHRoZSBjb2x1bW4gbnVtYmVyIGFuZAogKiAgaW5kZXhlcyBmcm9tIHRoZSByZXF1ZXN0IG9pZCBzbyB0aGF0IHlvdSBkb24ndCBoYXZlIHRvIGRvIHRoZQogKiAgY29tcGxleCB3b3JrIHRvIGRvIHRoYXQgcGFyc2luZyB3aXRoaW4geW91ciBvd24gY29kZS4KICoKICogIFRvIGRvIHRoaXMsIHRoZSB0YWJsZSBoYW5kbGVyIG5lZWRzIHRvIGtub3cgdXAgZnJvbnQgaG93IHlvdXIKICogIHRhYmxlIGlzIHN0cnVjdHVyZWQuICBUbyBpbmZvcm0gaXQgYWJvdXQgdGhpcywgeW91IGZpbGwgaW4gYQogKiAgdGFibGVfcmVnaXN0ZXJhdGlvbl9pbmZvIHN0cnVjdHVyZSB0aGF0IGlzIHBhc3NlZCB0byB0aGUgdGFibGUKICogIGhhbmRsZXIuICBJdCBjb250YWlucyB0aGUgYXNuIGluZGV4IHR5cGVzIGZvciB0aGUgdGFibGUgYXMgd2VsbCBhcwogKiAgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gY29sdW1uIHRoYXQgc2hvdWxkIGJlIHVzZWQuCiAqICAKICogIEB7CiAqLwoKLyoqIEdpdmVuIGEgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBvYmplY3QsIGNyZWF0ZXMgYSB0YWJsZSBoYW5kbGVyLgogKiAgWW91IGNhbiB1c2UgdGhpcyB0YWJsZSBoYW5kbGVyIGJ5IGluamVjdGluZyBpdCBpbnRvIGEgY2FsbGluZwogKiAgY2hhaW4uICBXaGVuIHRoZSBoYW5kbGVyIGdldHMgY2FsbGVkLCBpdCdsbCBkbyBwcm9jZXNzaW5nIGFuZAogKiAgc3RvcmUgaXQncyBpbmZvcm1hdGlvbiBpbnRvIHRoZSByZXF1ZXN0LT5wYXJlbnRfZGF0YSBzdHJ1Y3R1cmUuCiAqCiAqICBUaGUgdGFibGUgaGVscGVyIGhhbmRsZXIgcHVsbHMgb3V0IHRoZSBjb2x1bW4gbnVtYmVyIGFuZCBpbmRleGVzIGZyb20gCiAqICB0aGUgcmVxdWVzdCBvaWQgc28gdGhhdCB5b3UgZG9uJ3QgaGF2ZSB0byBkbyB0aGUgY29tcGxleCB3b3JrIG9mCiAqICBwYXJzaW5nIHdpdGhpbiB5b3VyIG93biBjb2RlLgogKgogKiAgQHBhcmFtIHRhYnJlcSBpcyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvIHN0cnVjdC4KICoJVGhlIHRhYmxlIGhhbmRsZXIgbmVlZHMgdG8ga25vdyB1cCBmcm9udCBob3cgeW91ciB0YWJsZSBpcyBzdHJ1Y3R1cmVkLgogKglBIG5ldHNubXBfdGFibGVfcmVnaXN0ZXJhdGlvbl9pbmZvIHN0cnVjdHVyZSB0aGF0IGlzIAogKglwYXNzZWQgdG8gdGhlIHRhYmxlIGhhbmRsZXIgc2hvdWxkIGNvbnRhaW4gdGhlIGFzbiBpbmRleCB0eXBlcyBmb3IgdGhlIAogKgl0YWJsZSBhcyB3ZWxsIGFzIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvbHVtbiB0aGF0IHNob3VsZCBiZSB1c2VkLgogKgogKiAgQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byBhIG5ldHNubXBfbWliX2hhbmRsZXIgc3RydWN0IHdoaWNoIGNvbnRhaW5zCiAqCXRoZSBoYW5kbGVyJ3MgbmFtZSBhbmQgdGhlIGFjY2VzcyBtZXRob2QKICoKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2dldF90YWJsZV9oYW5kbGVyKG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRhYnJlcSkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqcmV0ID0gTlVMTDsKCiAgICBpZiAoIXRhYnJlcSkgewogICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAibmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcihOVUxMKSBjYWxsZWRcbiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldCA9IG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoVEFCTEVfSEFORExFUl9OQU1FLCB0YWJsZV9oZWxwZXJfaGFuZGxlcik7CiAgICBpZiAocmV0KSB7CiAgICAgICAgcmV0LT5teXZvaWQgPSAodm9pZCAqKSB0YWJyZXE7CiAgICAgICAgdGFicmVxLT5udW1iZXJfaW5kZXhlcyA9IGNvdW50X3ZhcmJpbmRzKHRhYnJlcS0+aW5kZXhlcyk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqIGNyZWF0ZXMgYSB0YWJsZSBoYW5kbGVyIGdpdmVuIHRoZSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvIG9iamVjdCwKICogIGluc2VydHMgaXQgaW50byB0aGUgcmVxdWVzdCBjaGFpbiBhbmQgdGhlbiBjYWxscwogKiAgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkgdG8gcmVnaXN0ZXIgdGhlIHRhYmxlIGludG8gdGhlIGFnZW50LgogKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfdGFibGUobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YWJyZXEpCnsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcih0YWJyZXEpKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIocmVnaW5mbyk7Cn0KCi8qKiBFeHRyYWN0cyB0aGUgcHJvY2Vzc2VkIHRhYmxlIGluZm9ybWF0aW9uIGZyb20gYSBnaXZlbiByZXF1ZXN0LgogKiAgQ2FsbCB0aGlzIGZyb20gc3ViaGFuZGxlcnMgb24gYSByZXF1ZXN0IHRvIGV4dHJhY3QgdGhlIHByb2Nlc3NlZAogKiAgbmV0c25tcF9yZXF1ZXN0X2luZm8gaW5mb3JtYXRpb24uICBUaGUgcmVzdWx0aW5nIGluZm9ybWF0aW9uIGluY2x1ZGVzIHRoZQogKiAgaW5kZXggdmFsdWVzIGFuZCB0aGUgY29sdW1uIG51bWJlci4KICoKICogQHBhcmFtIHJlcXVlc3QgcG9wdWxhdGVkIG5ldHNubXAgcmVxdWVzdCBzdHJ1Y3R1cmUKICoKICogQHJldHVybiBwb3B1bGF0ZWQgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gc3RydWN0dXJlCiAqLwpORVRTTk1QX0lOTElORSBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqCm5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0KQp7CiAgICByZXR1cm4gKG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICopCiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdCwgVEFCTEVfSEFORExFUl9OQU1FKTsKfQoKLyoqIGV4dHJhY3RzIHRoZSByZWdpc3RlcmVkIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gb2JqZWN0IGZyb20gYQogKiAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBvYmplY3QgKi8KbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqCm5ldHNubXBfZmluZF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyhuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvKQp7CiAgICByZXR1cm4gKG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKikKICAgICAgICBuZXRzbm1wX2ZpbmRfaGFuZGxlcl9kYXRhX2J5X25hbWUocmVnaW5mbywgVEFCTEVfSEFORExFUl9OQU1FKTsKfQoKLyoqIGltcGxlbWVudHMgdGhlIHRhYmxlIGhlbHBlciBoYW5kbGVyICovCmludAp0YWJsZV9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CiAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YmxfaW5mbzsKICAgIGludCAgICAgICAgICAgICBvaWRfaW5kZXhfcG9zOwogICAgdW5zaWduZWQgaW50ICAgIG9pZF9jb2x1bW5fcG9zOwogICAgdW5zaWduZWQgaW50ICAgIHRtcF9pZHg7CiAgICBzaXplX3QJICAgIHRtcF9sZW47CiAgICBpbnQgICAgICAgICAgICAgaW5jb21wbGV0ZSwgb3V0X29mX3JhbmdlLCBjbGVhbmVkX3VwID0gMDsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SLCBuZWVkX3Byb2Nlc3NpbmcgPSAwOwogICAgb2lkICAgICAgICAgICAgKnRtcF9uYW1lOwogICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRibF9yZXFfaW5mbzsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmI7CgogICAgaWYgKCFyZWdpbmZvIHx8ICFoYW5kbGVyKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICBvaWRfaW5kZXhfcG9zICA9IHJlZ2luZm8tPnJvb3RvaWRfbGVuICsgMjsKICAgIG9pZF9jb2x1bW5fcG9zID0gcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAxOwogICAgdGJsX2luZm8gPSAobmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqKSBoYW5kbGVyLT5teXZvaWQ7CgogICAgaWYgKCghaGFuZGxlci0+bXl2b2lkKSB8fCAoIXRibF9pbmZvLT5pbmRleGVzKSkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJpbXByb3Blcmx5IHJlZ2lzdGVyZWQgdGFibGUgZm91bmRcbiIpOwogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJuYW1lOiAlcywgdGFibGUgaW5mbzogJXAsIGluZGV4ZXM6ICVwXG4iLAogICAgICAgICAgICAgICAgIGhhbmRsZXItPmhhbmRsZXJfbmFtZSwgaGFuZGxlci0+bXl2b2lkLCB0YmxfaW5mby0+aW5kZXhlcyk7CgogICAgICAgIC8qCiAgICAgICAgICogWFhYLXJrczogdW5yZWdpc3RlciB0YWJsZT8gCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KCiAgICBERUJVR0lGKCJoZWxwZXI6dGFibGU6cmVxIikgewogICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6cmVxIiwKICAgICAgICAgICAgICAgICAgICAiR290IHJlcXVlc3QgZm9yIGhhbmRsZXIgJXM6IGJhc2Ugb2lkOiIsCiAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+aGFuZGxlcl9uYW1lKSk7CiAgICAgICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6dGFibGU6cmVxIiwgcmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4pKTsKICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXEiLCAiXG4iKSk7CiAgICB9CiAgICAKICAgIC8qCiAgICAgKiBpZiB0aGUgYWdlbnQgcmVxdWVzdCBpbmZvIGhhcyBhIHN0YXRlIHJlZmVyZW5jZSwgdGhlbiB0aGlzIGlzIGEgCiAgICAgKiBsYXRlciBwYXNzIG9mIGEgc2V0IHJlcXVlc3QgYW5kIHdlIGNhbiBza2lwIGFsbCB0aGUgbG9va3VwIHN0dWZmLgogICAgICoKICAgICAqIHh4eC1ya3M6IHRoaXMgbWlnaHQgYnJlYWsgZm9yIGhhbmRsZXJzIHdoaWNoIG9ubHkgaGFuZGxlIG9uZSB2YXJiaW5kCiAgICAgKiBhdCBhIHRpbWUuLi4gdGhvc2UgaGFuZGxlcnMgc2hvdWxkIG5vdCBzYXZlIGRhdGEgYnkgdGhlaXIgaGFuZGxlcl9uYW1lCiAgICAgKiBpbiB0aGUgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8uIAogICAgICovCiAgICBpZiAobmV0c25tcF9hZ2VudF9nZXRfbGlzdF9kYXRhKHJlcWluZm8sIGhhbmRsZXItPm5leHQtPmhhbmRsZXJfbmFtZSkpIHsKICAgICAgICBpZiAoTU9ERV9JU19TRVQocmVxaW5mby0+bW9kZSkpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgICAgIH0gZWxzZSB7Ci8qKiBYWFgtcmtzOiBtZW1vcnkgbGVhay4gYWRkIGNsZWFudXAgaGFuZGxlcj8gKi8KICAgICAgICAgICAgbmV0c25tcF9mcmVlX2FnZW50X2RhdGFfc2V0cyhyZXFpbmZvKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCBNT0RFX0lTX1NFVChyZXFpbmZvLT5tb2RlKSAmJgogICAgICAgICAocmVxaW5mby0+bW9kZSAhPSBNT0RFX1NFVF9SRVNFUlZFMSkpIHsKICAgICAgICAvKgogICAgICAgICAqIGZvciBsYXRlciBzZXQgbW9kZXMsIHdlIGNhbiBza2lwIGFsbCB0aGUgaW5kZXggcGFyc2luZywKICAgICAgICAgKiBhbmQgd2UgYWx3YXlzIG5lZWQgdG8gbGV0IGNoaWxkIGhhbmRsZXJzIGhhdmUgYSBjaGFuY2UKICAgICAgICAgKiB0byBjbGVhbiB1cCwgaWYgdGhleSB3ZXJlIGNhbGxlZCBpbiB0aGUgZmlyc3QgcGxhY2UgKGkuZS4gaGF2ZQogICAgICAgICAqIGEgdmFsaWQgdGFibGUgaW5mbyBwb2ludGVyKS4KICAgICAgICAgKi8KICAgICAgICBpZihOVUxMID09IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3RzKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgidGFibGU6aGVscGVyIiwibm8gdGFibGUgaW5mbyBmb3Igc2V0IC0gc2tpcHBpbmdcbiIpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBuZWVkX3Byb2Nlc3NpbmcgPSAxOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBmb3IgUkVTRVJWRTEgYW5kIEdFVFMsIG9ubHkgY29udGludWUgaWYgd2UgaGF2ZSBhdCBsZWFzdAogICAgICAgICAqIG9uZSB2YWxpZCByZXF1ZXN0LgogICAgICAgICAqLwogICAgICAgICAgIAogICAgLyoKICAgICAqIGxvb3AgdGhyb3VnaCByZXF1ZXN0cwogICAgICovCgogICAgZm9yIChyZXF1ZXN0ID0gcmVxdWVzdHM7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXIgPSByZXF1ZXN0LT5yZXF1ZXN0dmI7CgogICAgICAgIERFQlVHTVNHT0lEKCgidmVyYm9zZTp0YWJsZSIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgIERFQlVHTVNHKCgidmVyYm9zZTp0YWJsZSIsICJcbiIpKTsKCiAgICAgICAgaWYgKHJlcXVlc3QtPnByb2Nlc3NlZCkgewogICAgICAgICAgICBERUJVR01TRygoInZlcmJvc2U6dGFibGUiLCAiYWxyZWFkeSBwcm9jZXNzZWRcbiIpKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3QtPnN0YXR1cyA9PSBTTk1QX0VSUl9OT0VSUk9SKTsKCiAgICAgICAgLyoKICAgICAgICAgKiB0aGlzIHNob3VsZCBwcm9iYWJseSBiZSBoYW5kbGVkIGZ1cnRoZXIgdXAgCiAgICAgICAgICovCiAgICAgICAgaWYgKChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUKSAmJiAodmFyLT50eXBlICE9IEFTTl9OVUxMKSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB2YWxpZCByZXF1ZXN0IGlmIEFTTl9OVUxMIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICIgIEdFVCB2YXIgdHlwZSBpcyBub3QgQVNOX05VTExcbiIpKTsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1dST05HVFlQRSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9TRVRfUkVTRVJWRTEpIHsKICAgICAgICAgICAgREVCVUdJRigiaGVscGVyOnRhYmxlOnNldCIpIHsKICAgICAgICAgICAgICAgIHVfY2hhciAgICAgICAgICpidWYgPSBOVUxMOwogICAgICAgICAgICAgICAgc2l6ZV90ICAgICAgICAgIGJ1Zl9sZW4gPSAwLCBvdXRfbGVuID0gMDsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6c2V0IiwgIiBTRVRfUkVRVUVTVCBmb3IgT0lEOiAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImhlbHBlcjp0YWJsZTpzZXQiLCB2YXItPm5hbWUsIHZhci0+bmFtZV9sZW5ndGgpKTsKICAgICAgICAgICAgICAgIG91dF9sZW4gPSAwOwogICAgICAgICAgICAgICAgaWYgKHNwcmludF9yZWFsbG9jX2J5X3R5cGUoJmJ1ZiwgJmJ1Zl9sZW4sICZvdXRfbGVuLCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLCAwLCAwLCAwKSkgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlOnNldCIsIiB0eXBlPSVkKCUwMngpLCB2YWx1ZT0lc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT50eXBlLCB2YXItPnR5cGUsIGJ1ZikpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6c2V0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgdHlwZT0lZCglMDJ4KSwgdmFsdWU9JXMgW1RSVU5DQVRFRF1cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPnR5cGUsIHZhci0+dHlwZSwgYnVmKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6c2V0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgdHlwZT0lZCglMDJ4KSwgdmFsdWU9W05JTF0gW1RSVU5DQVRFRF1cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPnR5cGUsIHZhci0+dHlwZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChidWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGZyZWUoYnVmKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayB0byBtYWtlIHN1cmUgaXRzIGluIHRhYmxlIHJhbmdlIAogICAgICAgICAqLwoKICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAwOwogICAgICAgIC8qCiAgICAgICAgICogaWYgb3VyIHJvb3Qgb2lkIGlzID4gdmFyLT5uYW1lIGFuZCB0aGlzIGlzIG5vdCBhIEdFVE5FWFQsIAogICAgICAgICAqIHRoZW4gdGhlIG9pZCBpcyBvdXQgb2YgcmFuZ2UuIChvbmx5IGNvbXBhcmUgdXAgdG8gc2hvcnRlciAKICAgICAgICAgKiBsZW5ndGgpIAogICAgICAgICAqLwogICAgICAgIGlmIChyZWdpbmZvLT5yb290b2lkX2xlbiA+IHZhci0+bmFtZV9sZW5ndGgpCiAgICAgICAgICAgIHRtcF9sZW4gPSB2YXItPm5hbWVfbGVuZ3RoOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdG1wX2xlbiA9IHJlZ2luZm8tPnJvb3RvaWRfbGVuOwogICAgICAgIGlmIChzbm1wX29pZF9jb21wYXJlKHJlZ2luZm8tPnJvb3RvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZSwgdG1wX2xlbikgPiAwKSB7CiAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgICAgICAgICAgaWYgKHZhci0+bmFtZSAhPSB2YXItPm5hbWVfbG9jKQogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRSh2YXItPm5hbWUpOwogICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHZhciwgcmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yb290b2lkX2xlbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwgIiAgb2lkIGlzIG91dCBvZiByYW5nZS5cbiIpKTsKICAgICAgICAgICAgICAgIG91dF9vZl9yYW5nZSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBpZiB2YXItPm5hbWUgaXMgbG9uZ2VyIHRoYW4gdGhlIHJvb3QsIG1ha2Ugc3VyZSBpdCBpcyAKICAgICAgICAgKiB0YWJsZS4xICh0YWJsZS5FTlRSWSkuICAKICAgICAgICAgKi8KICAgICAgICBlbHNlIGlmICgodmFyLT5uYW1lX2xlbmd0aCA+IHJlZ2luZm8tPnJvb3RvaWRfbGVuKSAmJgogICAgICAgICAgICAgICAgICh2YXItPm5hbWVbcmVnaW5mby0+cm9vdG9pZF9sZW5dICE9IDEpKSB7CiAgICAgICAgICAgIGlmICgodmFyLT5uYW1lW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSA8IDEpICYmCiAgICAgICAgICAgICAgICAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpKSB7CiAgICAgICAgICAgICAgICB2YXItPm5hbWVbcmVnaW5mby0+cm9vdG9pZF9sZW5dID0gMTsKICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGggPSByZWdpbmZvLT5yb290b2lkX2xlbjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG91dF9vZl9yYW5nZSA9IDE7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwgIiAgb2lkIGlzIG91dCBvZiByYW5nZS5cbiIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIGlmIGl0IGlzIG5vdCBpbiByYW5nZSwgdGhlbiBtYXJrIGl0IGluIHRoZSByZXF1ZXN0IGxpc3QgCiAgICAgICAgICogYmVjYXVzZSB3ZSBjYW4ndCBwcm9jZXNzIGl0LCBhbmQgc2V0IGFuIGVycm9yIHNvCiAgICAgICAgICogbm9ib2R5IGVsc2Ugd2FzdGVzIHRpbWUgdHJ5aW5nIHRvIHByb2Nlc3MgaXQgZWl0aGVyLiAgCiAgICAgICAgICovCiAgICAgICAgaWYgKG91dF9vZl9yYW5nZSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwgIiAgTm90IHByb2Nlc3NlZDogIikpOwogICAgICAgICAgICBERUJVR01TR09JRCgoImhlbHBlcjp0YWJsZSIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZSIsICJcbiIpKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqICBSZWplY3QgcmVxdWVzdHMgb2YgdGhlIGZvcm0gJ215VGFibGUuTicgICAoTiAhPSAxKQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9TRVRfUkVTRVJWRTEpCiAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfTk9UV1JJVEFCTEUpOwogICAgICAgICAgICBlbHNlIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUKQogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTk9TVUNIT0JKRUNUKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCiAgICAgICAgLyoKICAgICAgICAgKiBDaGVjayBjb2x1bW4gcmFuZ2VzOyBzZXQtdXAgdG8gcHVsbCBvdXQgaW5kZXhlcyBmcm9tIE9JRC4gCiAgICAgICAgICovCgogICAgICAgIGluY29tcGxldGUgPSAwOwogICAgICAgIHRibF9yZXFfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgIGlmIChOVUxMID09IHRibF9yZXFfaW5mbykgewogICAgICAgICAgICB0YmxfcmVxX2luZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvKTsKICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5yZWdfaW5mbyA9IHRibF9pbmZvOwogICAgICAgICAgICB0YmxfcmVxX2luZm8tPmluZGV4ZXMgPSBzbm1wX2Nsb25lX3ZhcmJpbmQodGJsX2luZm8tPmluZGV4ZXMpOwogICAgICAgICAgICB0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzID0gMDsgICAgICAgLyogbm9uZSB5ZXQgKi8KICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSB0YmxfcmVxX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9kYXRhX2ZyZWVfZnVuYykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICB1c2luZyBleGlzdGluZyB0YmxfcmVxX2luZm9cbiAiKSk7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGRvIHdlIGhhdmUgYSBjb2x1bW4/CiAgICAgICAgICovCiAgICAgICAgaWYgKHZhci0+bmFtZV9sZW5ndGggPiBvaWRfY29sdW1uX3BvcykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBvaWQgaXMgbG9uZyBlbm91Z2ggdG8gY29udGFpbiBDT0xVTU4gaW5mbwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLCAiICBoYXZlIGF0IGxlYXN0IGEgY29sdW1uICglZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc10pKTsKICAgICAgICAgICAgaWYgKHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc10gPCB0YmxfaW5mby0+bWluX2NvbHVtbikgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBidXQgaXQncyBsZXNzIHRoYW4gbWluICglZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YmxfaW5mby0+bWluX2NvbHVtbikpOwogICAgICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBmaXggY29sdW1uLCB0cnVuY2F0ZSB1c2VsZXNzIGNvbHVtbiBpbmZvIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGggPSBvaWRfY29sdW1uX3BvczsKICAgICAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSA9IHRibF9pbmZvLT5taW5fY29sdW1uOwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgb3V0X29mX3JhbmdlID0gMTsKICAgICAgICAgICAgfSBlbHNlIGlmICh2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdID4gdGJsX2luZm8tPm1heF9jb2x1bW4pCiAgICAgICAgICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAxOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSA9IHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc107CgogICAgICAgICAgICBpZiAob3V0X29mX3JhbmdlKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogdGhpcyBpcyBvdXQgb2YgcmFuZ2UuLi4gIHJlbW92ZSBmcm9tIHJlcXVlc3RzLCBmcmVlCiAgICAgICAgICAgICAgICAgKiBtZW1vcnkgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBvaWQgaXMgb3V0IG9mIHJhbmdlLiBOb3QgcHJvY2Vzc2VkOiAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImhlbHBlcjp0YWJsZSIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGUiLCAiXG4iKSk7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqICBSZWplY3QgcmVxdWVzdHMgb2YgdGhlIGZvcm0gJ215RW50cnkuTicgICAoaW52YWxpZCBOKQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMSkKICAgICAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQpCiAgICAgICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSE9CSkVDVCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB1c2UgY29sdW1uIHZlcmlmaWNhdGlvbiAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVsc2UgaWYgKHRibF9pbmZvLT52YWxpZF9jb2x1bW5zKSB7CiAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSA9CiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jbG9zZXN0X2NvbHVtbih2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsX2luZm8tPnZhbGlkX2NvbHVtbnMpOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLCAiICAgIGNsb3Nlc3QgY29sdW1uIGlzICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0pKTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiB4eHgtcmtzOiBkb2N1bWVudCB3aHkgdGhlIGNvbnRpbnVlLi4uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0YmxfcmVxX2luZm8tPmNvbG51bSA9PSAwKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKHRibF9yZXFfaW5mby0+Y29sbnVtICE9IHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc10pIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOmNvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICB3aGljaCBkb2Vzbid0IG1hdGNoIHJlcSAlZCAtIHRydW5jYXRpbmcgaW5kZXggaW5mb1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdKSk7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBkaWZmZXJlbnQgY29sdW1uISB0cnVuY2F0ZSB1c2VsZXNzIGluZGV4IGluZm8gCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lX2xlbmd0aCA9IG9pZF9jb2x1bW5fcG9zICsgMTsgLyogcG9zIGlzIDAgYmFzZWQgKi8KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB2YXItPm5hbWVfbGVuZ3RoIG1heSBoYXZlIGNoYW5nZWQgLSBjaGVjayBhZ2FpbiAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgoaW50KXZhci0+bmFtZV9sZW5ndGggPD0gb2lkX2luZGV4X3BvcykgeyAvKiBwb3MgaXMgMCBiYXNlZCAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgICAgbm90IGVub3VnaCBmb3IgaW5kZXhlc1xuIikpOwogICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuID0gMDsgLyoqIG5vbmUgYXZhaWxhYmxlICovCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogb2lkIGlzIGxvbmcgZW5vdWdoIHRvIGNvbnRhaW4gSU5ERVggaW5mbwogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmluZGV4X29pZF9sZW4gPQogICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGggLSBvaWRfaW5kZXhfcG9zOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgICAgaGF2ZSAlZCBieXRlcyBvZiBpbmRleFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbikpOwogICAgICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQodGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuIDwgTUFYX09JRF9MRU4pOwogICAgICAgICAgICAgICAgbWVtY3B5KHRibF9yZXFfaW5mby0+aW5kZXhfb2lkLCAmdmFyLT5uYW1lW29pZF9pbmRleF9wb3NdLAogICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiAqIHNpemVvZihvaWQpKTsKICAgICAgICAgICAgICAgIHRtcF9uYW1lID0gdGJsX3JlcV9pbmZvLT5pbmRleF9vaWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUIHx8CiAgICAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlID09IE1PREVfR0VUQlVMSykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBvaWQgaXMgTk9UIGxvbmcgZW5vdWdoIHRvIGNvbnRhaW4gY29sdW1uIG9yIGluZGV4IGluZm8sIHNvIHN0YXJ0CiAgICAgICAgICAgICAqIGF0IHRoZSBtaW5pbXVtIGNvbHVtbi4gU2V0IGluZGV4IG9pZCBsZW4gdG8gMCBiZWNhdXNlIHdlIGRvbid0CiAgICAgICAgICAgICAqIGhhdmUgYW55IGluZGV4IGluZm8gaW4gdGhlIE9JRC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICBubyBjb2x1bW4vaW5kZXggaW4gcmVxdWVzdFxuIikpOwogICAgICAgICAgICB0YmxfcmVxX2luZm8tPmluZGV4X29pZF9sZW4gPSAwOwogICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSA9IHRibF9pbmZvLT5taW5fY29sdW1uOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG9pZCBpcyBOT1QgbG9uZyBlbm91Z2ggdG8gY29udGFpbiBpbmRleCBpbmZvLAogICAgICAgICAgICAgKiBzbyB3ZSBjYW4ndCBkbyBhbnl0aGluZyB3aXRoIGl0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBSZWplY3QgcmVxdWVzdHMgb2YgdGhlIGZvcm0gJ215VGFibGUnIG9yICdteUVudHJ5JwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQgKSB7CiAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LCBTTk1QX05PU1VDSE9CSkVDVCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMSApIHsKICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogc2V0IHVwIHRtcF9sZW4gdG8gYmUgdGhlIG51bWJlciBvZiBPSURzIHdlIGhhdmUgYmV5b25kIHRoZSBjb2x1bW47CiAgICAgICAgICogdGhlc2Ugc2hvdWxkIGJlIHRoZSBpbmRleChzKSBmb3IgdGhlIHRhYmxlLiBJZiB0aGUgaW5kZXhfb2lkX2xlbgogICAgICAgICAqIGlzIDAsIHNldCB0bXBfbGVuIHRvIC0xIHNvIHRoYXQgd2hlbiB3ZSB0cnkgdG8gcGFyc2UgdGhlIGluZGV4IGJlbG93LAogICAgICAgICAqIHdlIGp1c3QgemVybyBmaWxsIGV2ZXJ5dGhpbmcuCiAgICAgICAgICovCiAgICAgICAgaWYgKHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiA9PSAwKSB7CiAgICAgICAgICAgIGluY29tcGxldGUgPSAxOwogICAgICAgICAgICB0bXBfbGVuID0gLTE7CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIHRtcF9sZW4gPSB0YmxfcmVxX2luZm8tPmluZGV4X29pZF9sZW47CgoKICAgICAgICAvKgogICAgICAgICAqIGZvciBlYWNoIGluZGV4IHR5cGUsIHRyeSB0byBleHRyYWN0IHRoZSBpbmRleCBmcm9tIHZhci0+bmFtZQogICAgICAgICAqLwogICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICBsb29raW5nIGZvciAlZCBpbmRleGVzXG4iLAogICAgICAgICAgICAgICAgICAgIHRibF9pbmZvLT5udW1iZXJfaW5kZXhlcykpOwogICAgICAgIGZvciAodG1wX2lkeCA9IDAsIHZiID0gdGJsX3JlcV9pbmZvLT5pbmRleGVzOwogICAgICAgICAgICAgdG1wX2lkeCA8IHRibF9pbmZvLT5udW1iZXJfaW5kZXhlczsKICAgICAgICAgICAgICsrdG1wX2lkeCwgdmIgPSB2Yi0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICBpZiAoaW5jb21wbGV0ZSAmJiB0bXBfbGVuKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaW5jb21wbGV0ZS9pbGxlZ2FsIE9JRCwgc2V0IHVwIGR1bW15IDAgdG8gcGFyc2UgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgb2lkIGluZGV4ZXMgbm90IGNvbXBsZXRlOiAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImhlbHBlcjp0YWJsZSIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGUiLCAiXG4iKSk7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIG5vIHNlbnNlIGluIHRyeWluZyBhbnltb3JlIGlmIHRoaXMgaXMgYSBHRVQvU0VULiAKICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgKiBSZWplY3QgcmVxdWVzdHMgb2YgdGhlIGZvcm0gJ215T2JqZWN0JyAgIChubyBpbnN0YW5jZSkKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgIT0gTU9ERV9HRVRORVhUKSB7CiAgICAgICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiAgICAgICAgICAgICAgICAgICAgY2xlYW5lZF91cCA9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0bXBfbGVuID0gMDsKICAgICAgICAgICAgICAgIHRtcF9uYW1lID0gKG9pZCAqKSAmIHRtcF9sZW47CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB0cnkgYW5kIHBhcnNlIGN1cnJlbnQgaW5kZXggCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocGFyc2Vfb25lX29pZF9pbmRleCgmdG1wX25hbWUsICZ0bXBfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YiwgMSkgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgICBpbmNvbXBsZXRlID0gMTsKICAgICAgICAgICAgICAgIHRtcF9sZW4gPSAtMTsgICAvKiBpcyB0aGlzIG5lY2Vzc2FyeT8gQmV0dGVyIHNhZmUgdGhhbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHNvcnJ5ICovCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZG8gbm90IGNvdW50IGluY29tcGxldGUgaW5kZXhlcyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIGdvdCAxIChpbmNvbXBsZXRlPSVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY29tcGxldGUpKTsKICAgICAgICAgICAgICAgIGlmIChpbmNvbXBsZXRlKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgKyt0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzOyAvKiogZ290IG9uZSBvayAqLwogICAgICAgICAgICAgICAgaWYgKHRtcF9sZW4gPD0gMCkgewogICAgICAgICAgICAgICAgICAgIGluY29tcGxldGUgPSAxOwogICAgICAgICAgICAgICAgICAgIHRtcF9sZW4gPSAtMTsgICAgICAgLyogaXMgdGhpcyBuZWNlc3Nhcnk/IEJldHRlciBzYWZlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB0aGFuIHNvcnJ5ICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAvKiogZm9yIGxvb3AgKi8KCiAgICAgICAgREVCVUdJRigiaGVscGVyOnRhYmxlOnJlc3VsdHMiKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsICIgIGZvdW5kICVkIGluZGV4ZXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXMpKTsKICAgICAgICAgICAgaWYgKCFjbGVhbmVkX3VwKSB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgICAgY291bnQ7CiAgICAgICAgICAgICAgICB1X2NoYXIgICAgICAgICAqYnVmID0gTlVMTDsKICAgICAgICAgICAgICAgIHNpemVfdCAgICAgICAgICBidWZfbGVuID0gMCwgb3V0X2xlbiA9IDA7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOnJlc3VsdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgY29sdW1uOiAlZCwgaW5kZXhlczogJWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzKSk7CiAgICAgICAgICAgICAgICBmb3IgKHZiID0gdGJsX3JlcV9pbmZvLT5pbmRleGVzLCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgIHZiICYmIGNvdW50IDwgdGJsX3JlcV9pbmZvLT5udW1iZXJfaW5kZXhlczsKICAgICAgICAgICAgICAgICAgICAgY291bnQrKywgdmIgPSB2Yi0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgICAgIG91dF9sZW4gPSAwOwogICAgICAgICAgICAgICAgICAgIGlmIChzcHJpbnRfcmVhbGxvY19ieV90eXBlKCZidWYsICZidWZfbGVuLCAmb3V0X2xlbiwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YiwgMCwgMCwgMCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgaW5kZXg6IHR5cGU9JWQoJTAyeCksIHZhbHVlPSVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT50eXBlLCB2Yi0+dHlwZSwgYnVmKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgaW5kZXg6IHR5cGU9JWQoJTAyeCksIHZhbHVlPSVzIFtUUlVOQ0FURURdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSwgdmItPnR5cGUsIGJ1ZikpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIGluZGV4OiB0eXBlPSVkKCUwMngpLCB2YWx1ZT1bTklMXSBbVFJVTkNBVEVEXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPnR5cGUsIHZiLT50eXBlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBmcmVlKGJ1Zik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwgIlxuIikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKCiAgICAgICAgLyoKICAgICAgICAgKiBkbyB3ZSBoYXZlIHN1ZmZpY2llbnQgaW5kZXggaW5mbyB0byBjb250aW51ZT8KICAgICAgICAgKi8KCiAgICAgICAgaWYgKChyZXFpbmZvLT5tb2RlICE9IE1PREVfR0VUTkVYVCkgJiYKICAgICAgICAgICAgKCh0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzICE9IHRibF9pbmZvLT5udW1iZXJfaW5kZXhlcykgfHwKICAgICAgICAgICAgICh0bXBfbGVuICE9IC0xKSkpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIGluZGV4KGVzKSBmb3IgdGFibGUgLSBza2lwcGluZ1xuIikpOwogICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LCBTTk1QX05PU1VDSElOU1RBTkNFKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3QtPnN0YXR1cyA9PSBTTk1QX0VSUl9OT0VSUk9SKTsKICAgICAgICAKICAgICAgICArK25lZWRfcHJvY2Vzc2luZzsKCiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yIGVhY2ggcmVxdWVzdCAqLwogICAgfQoKICAgIC8qCiAgICAgKiBiYWlsIGlmIHRoZXJlIGlzIG5vdGhpbmcgZm9yIG91ciBjaGlsZCBoYW5kbGVycwogICAgICovCiAgICBpZiAoMCA9PSBuZWVkX3Byb2Nlc3NpbmcpCiAgICAgICAgcmV0dXJuIHN0YXR1czsKCiAgICAvKgogICAgICogY2FsbCBvdXIgY2hpbGQgYWNjZXNzIGZ1bmN0aW9uIAogICAgICovCiAgICBzdGF0dXMgPQogICAgICAgIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwoKICAgIC8qCiAgICAgKiBjaGVjayBmb3Igc3BhcnNlIHRhYmxlcwogICAgICovCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpCiAgICAgICAgc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyKCBoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyApOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCiNkZWZpbmUgU1BBUlNFX1RBQkxFX0hBTkRMRVJfTkFNRSAic3BhcnNlX3RhYmxlIgoKLyoqIGltcGxlbWVudHMgdGhlIHNwYXJzZSB0YWJsZSBoZWxwZXIgaGFuZGxlcgogKiBAaW50ZXJuYWwKICoKICogQG5vdGUKICogVGhpcyBmdW5jdGlvbiBpcyBzdGF0aWMgdG8gcHJldmVudCBvdGhlcnMgZnJvbSBjYWxsaW5nIGl0CiAqIGRpcmVjdGx5LiBJdCBpdCBhdXRvbWF0aWNhbGx5IGNhbGxlZCBieSB0aGUgdGFibGUgaGVscGVyLAogKiAKICovCnN0YXRpYyBpbnQKc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CiAgICBvaWQgICAgICAgICAgICAgY29sb2lkW01BWF9PSURfTEVOXTsKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvOwoKICAgIC8qCiAgICAgKiBzaW5jZSB3ZSBkb24ndCBjYWxsIGNoaWxkIGhhbmRsZXJzLCB3YXJuIGlmIG9uZSB3YXMgcmVnaXN0ZXJlZAogICAgICogYmVuZWF0aCB1cy4gQSBzcGVjaWFsIGV4Y2VwdGlvbiBmb3IgdGhlIHRhYmxlIGhlbHBlciwgd2hpY2ggY2FsbHMKICAgICAqIHRoZSBoYW5kbGVyIGRpcmVjdGx5LiBVc2UgaGFuZGxlIGN1c3RvbSBmbGFnIHRvIG9ubHkgbG9nIG9uY2UuCiAgICAgKi8KICAgIGlmKCh0YWJsZV9oZWxwZXJfaGFuZGxlciAhPSBoYW5kbGVyLT5hY2Nlc3NfbWV0aG9kKSAmJgogICAgICAgKE5VTEwgIT0gaGFuZGxlci0+bmV4dCkpIHsKICAgICAgICAvKgogICAgICAgICAqIGFsd2F5cyB3YXJuIGlmIGNhbGxlZCB3aXRob3V0IG91ciBvd24gaGFuZGxlci4gSWYgd2UKICAgICAgICAgKiBoYXZlIG91ciBvd24gaGFuZGxlciwgdXNlIGN1c3RvbSBiaXQgMSB0byBvbmx5IGxvZyBvbmNlLgogICAgICAgICAqLwogICAgICAgIGlmKChzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIgIT0gaGFuZGxlci0+YWNjZXNzX21ldGhvZCkgfHwKICAgICAgICAgICAhKGhhbmRsZXItPmZsYWdzICYgTUlCX0hBTkRMRVJfQ1VTVE9NMSkpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsICJoYW5kbGVyICglcykgcmVnaXN0ZXJlZCBhZnRlciBzcGFyc2UgdGFibGUgIgogICAgICAgICAgICAgICAgICAgICAiaGFuZGVyIHdpbGwgbm90IGJlIGNhbGxlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+bmV4dC0+aGFuZGxlcl9uYW1lID8KICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+bmV4dC0+aGFuZGxlcl9uYW1lIDogIiIgKTsKICAgICAgICAgICAgaWYoc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyID09IGhhbmRsZXItPmFjY2Vzc19tZXRob2QpCiAgICAgICAgICAgICAgICBoYW5kbGVyLT5mbGFncyB8PSBNSUJfSEFORExFUl9DVVNUT00xOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgaWYgKChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX05VTEwgJiYgcmVxdWVzdC0+cHJvY2Vzc2VkKSB8fAogICAgICAgICAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGdldCBuZXh0IHNraXBwZWQgdGhpcyB2YWx1ZSBmb3IgdGhpcyBjb2x1bW4sIHdlCiAgICAgICAgICAgICAgICAgKiBuZWVkIHRvIGtlZXAgc2VhcmNoaW5nIGZvcndhcmQgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVCgoInNwYXJzZSIsICJyZXRyeSBmb3IgTk9TVUNISU5TVEFOQ0VcbiIpKTsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9IEFTTl9QUklWX1JFVFJZOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hPQkpFQ1QgfHwKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGdldCBuZXh0IGhhcyBjb21wbGV0ZWx5IGZpbmlzaGVkIHdpdGggdGhpcyBjb2x1bW4sCiAgICAgICAgICAgICAgICAgKiBzbyB3ZSBuZWVkIHRvIHRyeSB3aXRoIHRoZSBuZXh0IGNvbHVtbiAoaWYgYW55KQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBERUJVR01TR1QoKCJzcGFyc2UiLCAicmV0cnkgZm9yIE5PU1VDSE9CSkVDVFxuIikpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mby0+Y29sbnVtID0gbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbih0YWJsZV9pbmZvKTsKICAgICAgICAgICAgICAgIGlmICgwICE9IHRhYmxlX2luZm8tPmNvbG51bSkgewogICAgICAgICAgICAgICAgICAgIG1lbWNweShjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbl0gICA9IDE7ICAgLyogdGFibGUuZW50cnkgbm9kZSAqLwogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRhYmxlX2luZm8tPmNvbG51bTsKICAgICAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQocmVxdWVzdC0+cmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuICsgMik7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gQVNOX1BSSVZfUkVUUlk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIElmIHdlIGRvbid0IGhhdmUgY29sdW1uIGluZm8sIHJlc2V0IHRvIG51bGwgc28KICAgICAgICAgICAgICAgICAgICAgKiB0aGUgYWdlbnQgd2lsbCBtb3ZlIG9uIHRvIHRoZSBuZXh0IHRhYmxlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKLyoqIGNyZWF0ZSBzcGFyc2UgdGFibGUgaGFuZGxlcgogKi8KbmV0c25tcF9taWJfaGFuZGxlciAqCm5ldHNubXBfc3BhcnNlX3RhYmxlX2hhbmRsZXJfZ2V0KHZvaWQpCnsKICAgIHJldHVybiBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFNQQVJTRV9UQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIpOwp9CgovKiogY3JlYXRlcyBhIHRhYmxlIGhhbmRsZXIgZ2l2ZW4gdGhlIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gb2JqZWN0LAogKiAgaW5zZXJ0cyBpdCBpbnRvIHRoZSByZXF1ZXN0IGNoYWluIGFuZCB0aGVuIGNhbGxzCiAqICBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKSB0byByZWdpc3RlciB0aGUgdGFibGUgaW50byB0aGUgYWdlbnQuCiAqLwppbnQKbmV0c25tcF9zcGFyc2VfdGFibGVfcmVnaXN0ZXIobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YWJyZXEpCnsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywKICAgICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFNQQVJTRV9UQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIpKTsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcih0YWJyZXEpKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIocmVnaW5mbyk7Cn0KCgovKiogQnVpbGRzIHRoZSByZXN1bHQgdG8gYmUgcmV0dXJuZWQgdG8gdGhlIGFnZW50IGdpdmVuIHRoZSB0YWJsZSBpbmZvcm1hdGlvbi4KICogIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIHJldHVybiByZXN1bHRzIGZyb20gbG93ZWwgbGV2ZWwgaGFuZGxlcnMgdG8KICogIHRoZSBhZ2VudC4gIEl0IHRha2VzIGNhcmUgb2YgYnVpbGRpbmcgdGhlIHByb3BlciByZXN1bHRpbmcgb2lkCiAqICAoY29udGFpbmluZyBwcm9wZXIgaW5kZXhpbmcpIGFuZCBpbnNlcnRzIHRoZSByZXN1bHQgdmFsdWUgaW50byB0aGUKICogIHJldHVybmluZyB2YXJiaW5kLgogKi8KaW50Cm5ldHNubXBfdGFibGVfYnVpbGRfcmVzdWx0KG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyIHR5cGUsIHVfY2hhciAqIHJlc3VsdCwgc2l6ZV90IHJlc3VsdF9sZW4pCnsKCiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcjsKCiAgICBpZiAoIXJlcWluZm8gfHwgIXRhYmxlX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHZhciA9IHJlcWluZm8tPnJlcXVlc3R2YjsKCiAgICBpZiAodmFyLT5uYW1lICE9IHZhci0+bmFtZV9sb2MpCiAgICAgICAgZnJlZSh2YXItPm5hbWUpOwogICAgdmFyLT5uYW1lID0gTlVMTDsKCiAgICBpZiAobmV0c25tcF90YWJsZV9idWlsZF9vaWQocmVnaW5mbywgcmVxaW5mbywgdGFibGVfaW5mbykgIT0KICAgICAgICBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZSh2YXIsIHR5cGUsIHJlc3VsdCwgcmVzdWx0X2xlbik7CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKCi8qKiBnaXZlbiBhIHJlZ2lzdHJhdGlvbiBpbmZvIG9iamVjdCwgYSByZXF1ZXN0IG9iamVjdCBhbmQgdGhlIHRhYmxlCiAqICBpbmZvIG9iamVjdCBpdCBidWlsZHMgdGhlIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSBvaWQgZnJvbSB0aGUKICogIGluZGV4IHZhbHVlcyBhbmQgY29sdW1uIGluZm9ybWF0aW9uIGZvdW5kIGluIHRoZSB0YWJsZV9pbmZvCiAqICBvYmplY3QuIEluZGV4IHZhbHVlcyBhcmUgZXh0cmFjdGVkIGZyb20gdGhlIHRhYmxlX2luZm8gdmFyYmluZHMuCiAqLwppbnQKbmV0c25tcF90YWJsZV9idWlsZF9vaWQobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvKQp7CiAgICBvaWQgICAgICAgICAgICAgdG1wb2lkW01BWF9PSURfTEVOXTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwoKICAgIGlmICghcmVnaW5mbyB8fCAhcmVxaW5mbyB8fCAhdGFibGVfaW5mbykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgLyoKICAgICAqIHh4eC1ya3M6IGluZWZmaWNlbnQuIHdlIGRvIGEgY29weSBoZXJlLCB0aGVuIGJ1aWxkX29pZCBkb2VzIGl0CiAgICAgKiAgICAgICAgICBhZ2Fpbi4gZWl0aGVyIGNvbWUgdXAgd2l0aCBhIG5ldyB1dGlsaXR5IHJvdXRpbmUsIG9yCiAgICAgKiAgICAgICAgICBkbyBzb21lIGhpamlua3MgaGVyZSB0byBlbGltaW5hdGUgZXh0cmEgY29weS4KICAgICAqICAgICAgICAgIFByb2JhYmx5IGNvdWxkIG1ha2Ugc3VyZSBhbGwgY2FsbGVycyBoYXZlIHRoZQogICAgICogICAgICAgICAgaW5kZXggJiB2YXJpYWJsZSBsaXN0IHVwZGF0ZWQsIGFuZCB1c2UKICAgICAqICAgICAgICAgIG5ldHNubXBfdGFibGVfYnVpbGRfb2lkX2Zyb21faW5kZXgoKSBpbnN0ZWFkIG9mIGFsbCB0aGlzLgogICAgICovCiAgICBtZW1jcHkodG1wb2lkLCByZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiAqIHNpemVvZihvaWQpKTsKICAgIHRtcG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbl0gPSAxOyAgIC8qKiAuRW50cnkgKi8KICAgIHRtcG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbiArIDFdID0gdGFibGVfaW5mby0+Y29sbnVtOyAvKiogLmNvbHVtbiAqLwoKICAgIHZhciA9IHJlcWluZm8tPnJlcXVlc3R2YjsKICAgIGlmIChidWlsZF9vaWQoJnZhci0+bmFtZSwgJnZhci0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHRtcG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAyLCB0YWJsZV9pbmZvLT5pbmRleGVzKQogICAgICAgICE9IFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKLyoqIGdpdmVuIGEgcmVnaXN0cmF0aW9uIGluZm8gb2JqZWN0LCBhIHJlcXVlc3Qgb2JqZWN0IGFuZCB0aGUgdGFibGUKICogIGluZm8gb2JqZWN0IGl0IGJ1aWxkcyB0aGUgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lIG9pZCBmcm9tIHRoZQogKiAgaW5kZXggdmFsdWVzIGFuZCBjb2x1bW4gaW5mb3JtYXRpb24gZm91bmQgaW4gdGhlIHRhYmxlX2luZm8KICogIG9iamVjdC4gIEluZGV4IHZhbHVlcyBhcmUgZXh0cmFjdGVkIGZyb20gdGhlIHRhYmxlX2luZm8gaW5kZXggb2lkLgogKi8KaW50Cm5ldHNubXBfdGFibGVfYnVpbGRfb2lkX2Zyb21faW5kZXgobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbykKewogICAgb2lkICAgICAgICAgICAgIHRtcG9pZFtNQVhfT0lEX0xFTl07CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcjsKICAgIGludCAgICAgICAgICAgICBsZW47CgogICAgaWYgKCFyZWdpbmZvIHx8ICFyZXFpbmZvIHx8ICF0YWJsZV9pbmZvKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICB2YXIgPSByZXFpbmZvLT5yZXF1ZXN0dmI7CiAgICBsZW4gPSByZWdpbmZvLT5yb290b2lkX2xlbjsKICAgIG1lbWNweSh0bXBvaWQsIHJlZ2luZm8tPnJvb3RvaWQsIGxlbiAqIHNpemVvZihvaWQpKTsKICAgIHRtcG9pZFtsZW4rK10gPSAxOyAgICAgICAgICAvKiAuRW50cnkgKi8KICAgIHRtcG9pZFtsZW4rK10gPSB0YWJsZV9pbmZvLT5jb2xudW07IC8qIC5jb2x1bW4gKi8KICAgIG1lbWNweSgmdG1wb2lkW2xlbl0sIHRhYmxlX2luZm8tPmluZGV4X29pZCwKICAgICAgICAgICB0YWJsZV9pbmZvLT5pbmRleF9vaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgbGVuICs9IHRhYmxlX2luZm8tPmluZGV4X29pZF9sZW47CiAgICBzbm1wX3NldF92YXJfb2JqaWQoIHZhciwgdG1wb2lkLCBsZW4gKTsKCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKiogcGFyc2VzIGFuIE9JRCBpbnRvIHRhYmxlIGluZGV4c2VzICovCmludApuZXRzbm1wX3VwZGF0ZV92YXJpYWJsZV9saXN0X2Zyb21faW5kZXgobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRyaSkKewogICAgaWYgKCF0cmkpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIC8qCiAgICAgKiBmcmVlIGFueSBleGlzdGluZyBhbGxvY2F0ZWQgbWVtb3J5LCB0aGVuIHBhcnNlIG9pZCBpbnRvIHZhcmJpbmRzCiAgICAgKi8KICAgIHNubXBfcmVzZXRfdmFyX2J1ZmZlcnMoIHRyaS0+aW5kZXhlcyk7CgogICAgcmV0dXJuIHBhcnNlX29pZF9pbmRleGVzKHRyaS0+aW5kZXhfb2lkLCB0cmktPmluZGV4X29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpLT5pbmRleGVzKTsKfQoKLyoqIGJ1aWxkcyBhbiBvaWQgZ2l2ZW4gYSBzZXQgb2YgaW5kZXhlcy4gKi8KaW50Cm5ldHNubXBfdXBkYXRlX2luZGV4ZXNfZnJvbV92YXJpYWJsZV9saXN0KG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0cmkpCnsKICAgIGlmICghdHJpKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICByZXR1cm4gYnVpbGRfb2lkX25vYWxsb2ModHJpLT5pbmRleF9vaWQsIHNpemVvZih0cmktPmluZGV4X29pZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRyaS0+aW5kZXhfb2lkX2xlbiwgTlVMTCwgMCwgdHJpLT5pbmRleGVzKTsKfQoKLyoqCiAqIGNoZWNrcyB0aGUgb3JpZ2luYWwgcmVxdWVzdCBhZ2FpbnN0IHRoZSBjdXJyZW50IGRhdGEgYmVpbmcgcGFzc2VkIGluIGlmIAogKiBpdHMgZ3JlYXRlciB0aGFuIHRoZSByZXF1ZXN0IG9pZCBidXQgbGVzcyB0aGFuIHRoZSBjdXJyZW50IHZhbGlkCiAqIHJldHVybiwgc2V0IHRoZSBjdXJyZW50IHZhbGlkIHJldHVybiB0byB0aGUgbmV3IHZhbHVlLgogKiAKICogcmV0dXJucyAxIGlmIG91dHZhciB3YXMgcmVwbGFjZWQgd2l0aCB0aGUgb2lkIGZyb20gbmV3dmFyIChzdWNjZXNzKS4KICogcmV0dXJucyAwIGlmIG5vdC4gCiAqLwppbnQKbmV0c25tcF9jaGVja19nZXRuZXh0X3JlcGx5KG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHByZWZpeF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiBuZXd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiogb3V0dmFyKQp7CiAgICBvaWQgICAgICBteW5hbWVbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgbXluYW1lX2xlbjsKCiAgICBidWlsZF9vaWRfbm9hbGxvYyhteW5hbWUsIE1BWF9PSURfTEVOLCAmbXluYW1lX2xlbiwKICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCwgcHJlZml4X2xlbiwgbmV3dmFyKTsKICAgIC8qCiAgICAgKiBpcyB0aGUgYnVpbGQgb2YgdGhlIG5ldyBpbmRleGVzIGxlc3MgdGhhbiBvdXIgY3VycmVudCByZXN1bHQgCiAgICAgKi8KICAgIGlmICgoISgqb3V0dmFyKSB8fCBzbm1wX29pZF9jb21wYXJlKG15bmFtZSArIHByZWZpeF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWVfbGVuIC0gcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqb3V0dmFyKS0+bmFtZSArIHByZWZpeF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKm91dHZhciktPm5hbWVfbGVuZ3RoIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeF9sZW4pIDwgMCkpIHsKICAgICAgICAvKgogICAgICAgICAqIGFuZCBncmVhdGVyIHRoYW4gdGhlIHJlcXVlc3RlZCBvaWQgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobXluYW1lLCBteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoKSA+IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdGhlIG5ldyByZXN1bHQgbXVzdCBiZSBiZXR0ZXIgdGhhbiB0aGUgb2xkIAogICAgICAgICAgICAgKi8KI2lmZGVmIE9OTFlfV09SS1NfV0lUSF9PTkVfVkFSQklORAogICAgICAgICAgICBpZiAoISpvdXR2YXIpCiAgICAgICAgICAgICAgICAqb3V0dmFyID0gc25tcF9jbG9uZV92YXJiaW5kKG5ld3Zhcik7CgkgICAgZWxzZQogICAgICAgICAgICAgICAgLyogCiAgICAgICAgICAgICAgICAgKiBUT0RPOiB3YWxrIHRoZSBmdWxsIHZhcmJpbmQgbGlzdCwgc2V0dGluZwogICAgICAgICAgICAgICAgICogICAgICAgKmFsbCogdGhlIHZhbHVlcyAtIG5vdCBqdXN0IHRoZSBmaXJzdC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKCpvdXR2YXIsIG5ld3Zhci0+dHlwZSwKCQkJCW5ld3Zhci0+dmFsLnN0cmluZywgbmV3dmFyLT52YWxfbGVuKTsKI2Vsc2UgIC8qIEludGVyaW0gcmVwbGFjZW1lbnQgYXBwcm9hY2ggLSBsZXNzIGVmZmljaWVudCwgYnV0IGl0IHdvcmtzISAqLwogICAgICAgICAgICBpZiAoKm91dHZhcikKICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCpvdXR2YXIpOwogICAgICAgICAgICAqb3V0dmFyID0gc25tcF9jbG9uZV92YXJiaW5kKG5ld3Zhcik7CiNlbmRpZgogICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQoKm91dHZhciwgbXluYW1lLCBteW5hbWVfbGVuKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9CgovKiogQH0gKi8KCi8qCiAqIGludGVybmFsIHJvdXRpbmVzIAogKi8Kdm9pZAp0YWJsZV9kYXRhX2ZyZWVfZnVuYyh2b2lkICpkYXRhKQp7CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqaW5mbyA9IChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqKSBkYXRhOwogICAgaWYgKCFpbmZvKQogICAgICAgIHJldHVybjsKICAgIHNubXBfZnJlZV92YXJiaW5kKGluZm8tPmluZGV4ZXMpOwogICAgZnJlZShpbmZvKTsKfQoKCgpzdGF0aWMgdm9pZAp0YWJsZV9oZWxwZXJfY2xlYW51cChuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsIGludCBzdGF0dXMpCnsKICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdCwgc3RhdHVzKTsKICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhyZXF1ZXN0KTsKICAgIGlmICghcmVxdWVzdCkKICAgICAgICByZXR1cm47CiAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YSA9IE5VTEw7Cn0KCgovKgogKiBmaW5kIHRoZSBjbG9zZXN0IGNvbHVtbiB0byBjdXJyZW50ICh3aGljaCBtYXkgYmUgY3VycmVudCkuCiAqCiAqIGNhbGxlZCB3aGVuIGEgdGFibGUgcnVucyBvdXQgb2Ygcm93cyBmb3IgY29sdW1uIFguIFRoaXMKICogZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggY3VycmVudCA9IFggKyAxLCB0byB2ZXJpZnkgdGhhdAogKiBYICsgMSBpcyBhIHZhbGlkIGNvbHVtbiwgb3IgZmluZCB0aGUgbmV4dCBjbG9zZXN0IGNvbHVtbiBpZiBub3QuCiAqCiAqIEFsbCBsaXN0IHR5cGVzIHNob3VsZCBiZSBzb3J0ZWQsIGxvd2VzdCB0byBoaWdoZXN0LgogKi8KdW5zaWduZWQgaW50Cm5ldHNubXBfY2xvc2VzdF9jb2x1bW4odW5zaWduZWQgaW50IGN1cnJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jb2x1bW5faW5mbyAqdmFsaWRfY29sdW1ucykKewogICAgdW5zaWduZWQgaW50ICAgIGNsb3Nlc3QgPSAwOwogICAgaW50ICAgICAgICAgICAgIGlkeDsKCiAgICBpZiAodmFsaWRfY29sdW1ucyA9PSBOVUxMKQogICAgICAgIHJldHVybiAwOwoKICAgIGZvciggOyB2YWxpZF9jb2x1bW5zOyB2YWxpZF9jb2x1bW5zID0gdmFsaWRfY29sdW1ucy0+bmV4dCkgewoKICAgICAgICBpZiAodmFsaWRfY29sdW1ucy0+aXNSYW5nZSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiBjdXJyZW50IDwgbG93IHJhbmdlLCBpdCBtaWdodCBiZSBjbG9zZXN0LgogICAgICAgICAgICAgKiBvdGhlcndpc2UsIGlmIGl0J3MgPCBoaWdoIHJhbmdlLCBjdXJyZW50IGlzIGluCiAgICAgICAgICAgICAqIHRoZSByYW5nZSwgYW5kIHRodXMgaXMgYW4gZXhhY3QgbWF0Y2guCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA8IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMucmFuZ2VbMF0pIHsKICAgICAgICAgICAgICAgIGlmICggKHZhbGlkX2NvbHVtbnMtPmRldGFpbHMucmFuZ2VbMF0gPCBjbG9zZXN0KSB8fAogICAgICAgICAgICAgICAgICAgICAoMCA9PSBjbG9zZXN0KSkgewogICAgICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLnJhbmdlWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnQgPD0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5yYW5nZVsxXSkgewogICAgICAgICAgICAgICAgY2xvc2VzdCA9IGN1cnJlbnQ7CiAgICAgICAgICAgICAgICBicmVhazsgICAgICAgLyogY2FuIG5vdCBnZXQgYW55IGNsb3NlciEgKi8KICAgICAgICAgICAgfQoKICAgICAgICB9IC8qIHJhbmdlICovCiAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgLyogbGlzdCAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiBjdXJyZW50IDwgZmlyc3QgaXRlbSwgbm8gbmVlZCB0byBpdGVyYXRlIG92ZXIgbGlzdC4KICAgICAgICAgICAgICogdGhhdCBpdGVtIGlzIGVpdGhlciBjbG9zZXN0LCBvciBub3QuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA8IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFswXSkgewogICAgICAgICAgICAgICAgaWYgKCh2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbMF0gPCBjbG9zZXN0KSB8fAogICAgICAgICAgICAgICAgICAgICgwID09IGNsb3Nlc3QpKQogICAgICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbMF07CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqIGlmIGN1cnJlbnQgPiBsYXN0IGl0ZW0gaW4gbGlzdCwgbm8gbmVlZCB0byBpdGVyYXRlICovCiAgICAgICAgICAgIGlmIChjdXJyZW50ID4KICAgICAgICAgICAgICAgIHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFsoaW50KXZhbGlkX2NvbHVtbnMtPmxpc3RfY291bnQgLSAxXSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAgICAgICAvKiBub3QgaW4gbGlzdCByYW5nZS4gKi8KCiAgICAgICAgICAgIC8qKiBza2lwIGFueXRoaW5nIGxlc3MgdGhhbiBjdXJyZW50Ki8KICAgICAgICAgICAgZm9yIChpZHggPSAwOyB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XSA8IGN1cnJlbnQ7ICsraWR4KQogICAgICAgICAgICAgICAgOwogICAgICAgICAgICAKICAgICAgICAgICAgLyoqIGNoZWNrIGZvciBleGFjdCBtYXRjaCAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA9PSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XSkgewogICAgICAgICAgICAgICAgY2xvc2VzdCA9IGN1cnJlbnQ7CiAgICAgICAgICAgICAgICBicmVhazsgICAgICAvKiBjYW4gbm90IGdldCBhbnkgY2xvc2VyISAqLwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiogbGlzdFtpZHhdID4gY3VycmVudDsgaXMgaXQgPCBjbG9zZXN0PyAqLwogICAgICAgICAgICBpZiAoKHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFtpZHhdIDwgY2xvc2VzdCkgfHwKICAgICAgICAgICAgICAgICgwID09IGNsb3Nlc3QpKQogICAgICAgICAgICAgICAgY2xvc2VzdCA9IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFtpZHhdOwoKICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAvKiBsaXN0ICovCiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yICovCgogICAgcmV0dXJuIGNsb3Nlc3Q7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIHNldHVwIHRoZSB0YWJsZSdzIGRlZmluaXRpb24gd2l0aGluCiAqIHlvdXIgbW9kdWxlJ3MgaW5pdGlhbGl6ZSBmdW5jdGlvbiwgaXQgdGFrZXMgYSB2YXJpYWJsZSBpbmRleCBwYXJhbWV0ZXIgbGlzdAogKiBmb3IgZXhhbXBsZTogdGhlIHRhYmxlX2luZm8gc3RydWN0dXJlIGlzIGZvbGxvd2VkIGJ5IHR3byBpbnRlZ2VyIGluZGV4IHR5cGVzCiAqIG5ldHNubXBfdGFibGVfaGVscGVyX2FkZF9pbmRleGVzKAogKiAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8sICAgCiAqCSAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAgCiAqCQkgICAgQVNOX0lOVEVHRVIsICAKICoJCSAgICAwKTsKICoKICogQHBhcmFtIHRpbmZvIGlzIGEgcG9pbnRlciB0byBhIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gc3RydWN0LgogKglUaGUgdGFibGUgaGFuZGxlciBuZWVkcyB0byBrbm93IHVwIGZyb250IGhvdyB5b3VyIHRhYmxlIGlzIHN0cnVjdHVyZWQuCiAqCUEgbmV0c25tcF90YWJsZV9yZWdpc3RlcmF0aW9uX2luZm8gc3RydWN0dXJlIHRoYXQgaXMgCiAqCXBhc3NlZCB0byB0aGUgdGFibGUgaGFuZGxlciBzaG91bGQgY29udGFpbiB0aGUgYXNuIGluZGV4IHR5cGVzIGZvciB0aGUgCiAqCXRhYmxlIGFzIHdlbGwgYXMgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gY29sdW1uIHRoYXQgc2hvdWxkIGJlIHVzZWQuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKi8Kdm9pZAojaWYgSEFWRV9TVERBUkdfSApuZXRzbm1wX3RhYmxlX2hlbHBlcl9hZGRfaW5kZXhlcyhuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0aW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uKQojZWxzZQpuZXRzbm1wX3RhYmxlX2hlbHBlcl9hZGRfaW5kZXhlcyh2YV9hbGlzdCkKICAgICB2YV9kY2wKI2VuZGlmCnsKICAgIHZhX2xpc3QgICAgICAgICBkZWJ1Z2FyZ3M7CiAgICBpbnQgICAgICAgICAgICAgdHlwZTsKCiNpZiBIQVZFX1NUREFSR19ICiAgICB2YV9zdGFydChkZWJ1Z2FyZ3MsIHRpbmZvKTsKI2Vsc2UKICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRpbmZvOwoKICAgIHZhX3N0YXJ0KGRlYnVnYXJncyk7CiAgICB0aW5mbyA9IHZhX2FyZyhkZWJ1Z2FyZ3MsIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKik7CiNlbmRpZgoKICAgIHdoaWxlICgodHlwZSA9IHZhX2FyZyhkZWJ1Z2FyZ3MsIGludCkpICE9IDApIHsKICAgICAgICBuZXRzbm1wX3RhYmxlX2hlbHBlcl9hZGRfaW5kZXgodGluZm8sIHR5cGUpOwogICAgfQoKICAgIHZhX2VuZChkZWJ1Z2FyZ3MpOwp9CgpzdGF0aWMgdm9pZApfcm93X3N0YXNoX2RhdGFfbGlzdF9mcmVlKHZvaWQgKnB0cikgewogICAgbmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKnRtcCA9IChuZXRzbm1wX29pZF9zdGFzaF9ub2RlICoqKXB0cjsKICAgIG5ldHNubXBfb2lkX3N0YXNoX2ZyZWUodG1wLCBOVUxMKTsKICAgIGZyZWUocHRyKTsKfQoKLyoqIHJldHVybnMgYSByb3ctd2lkZSBwbGFjZSB0byBzdG9yZSBkYXRhIGluLgogICAgQHRvZG8gVGhpcyBmdW5jdGlvbiB3aWxsIGxpa2VseSBjaGFuZ2UgdG8gYWRkIGZyZWUgcG9pbnRlciBmdW5jdGlvbnMuICovCm5ldHNubXBfb2lkX3N0YXNoX25vZGUgKioKbmV0c25tcF90YWJsZV9nZXRfb3JfY3JlYXRlX3Jvd19zdGFzaChuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1X2NoYXIgKiBzdG9yYWdlX25hbWUpCnsKICAgIG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKipzdGFzaHAgPSBOVUxMOwogICAgc3Rhc2hwID0gKG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKiopCiAgICAgICAgbmV0c25tcF9hZ2VudF9nZXRfbGlzdF9kYXRhKHJlcWluZm8sIHN0b3JhZ2VfbmFtZSk7CgogICAgaWYgKCFzdGFzaHApIHsKICAgICAgICAvKgogICAgICAgICAqIGhhc24ndCBiZSBjcmVhdGVkIHlldC4gIHdlIGNyZWF0ZSBpdCBoZXJlLiAKICAgICAgICAgKi8KICAgICAgICBzdGFzaHAgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKik7CgogICAgICAgIGlmICghc3Rhc2hwKQogICAgICAgICAgICByZXR1cm4gTlVMTDsgICAgICAgIC8qIGFjay4gb3V0IG9mIG1lbSAqLwoKICAgICAgICBuZXRzbm1wX2FnZW50X2FkZF9saXN0X2RhdGEocmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0KHN0b3JhZ2VfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXNocCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9yb3dfc3Rhc2hfZGF0YV9saXN0X2ZyZWUpKTsKICAgIH0KICAgIHJldHVybiBzdGFzaHA7Cn0KCi8qCiAqIGFkdmFuY2UgdGhlIHRhYmxlIGluZm8gY29sbnVtIHRvIHRoZSBuZXh0IGNvbHVtbiwgb3IgMCBpZiB0aGVyZSBhcmUgbm8gbW9yZQogKgogKiBAcmV0dXJuIG5ldyBjb2x1bW4sIG9yIDAgaWYgdGhlcmUgYXJlIG5vIG1vcmUKICovCnVuc2lnbmVkIGludApuZXRzbm1wX3RhYmxlX25leHRfY29sdW1uKG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvKQp7CiAgICBpZiAoTlVMTCA9PSB0YWJsZV9pbmZvKQogICAgICAgIHJldHVybiAwOwoKICAgIC8qCiAgICAgKiB0cnkgYW5kIHZhbGlkYXRlIG5leHQgY29sdW1uCiAgICAgKi8KICAgIGlmICh0YWJsZV9pbmZvLT5yZWdfaW5mby0+dmFsaWRfY29sdW1ucykKICAgICAgICByZXR1cm4gbmV0c25tcF9jbG9zZXN0X2NvbHVtbih0YWJsZV9pbmZvLT5jb2xudW0gKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8tPnJlZ19pbmZvLT52YWxpZF9jb2x1bW5zKTsKICAgIAogICAgLyoKICAgICAqIGNhbid0IHZhbGlkYXRlLiBhc3N1bWUgMS4ubWF4X2NvbHVtbiBhcmUgdmFsaWQKICAgICAqLwogICAgaWYgKHRhYmxlX2luZm8tPmNvbG51bSA8IHRhYmxlX2luZm8tPnJlZ19pbmZvLT5tYXhfY29sdW1uKQogICAgICAgIHJldHVybiB0YWJsZV9pbmZvLT5jb2xudW0gKyAxOwogICAgCiAgICByZXR1cm4gMDsgLyogb3V0IG9mIHJhbmdlICovCn0K