LyoKICogIENvcHlyaWdodAkxOTk0CUVyaWMgWW91bmRhbGUgJiBFcmlrIEJvcwogKiAgQ29weXJpZ2h0CTE5OTUJTWFydGluIHZvbiBM9ndpcwogKiAgQ29weXJpZ2h0ICAgMTk5Ni05OCBNYXJjdXMgTWVpc3NuZXIKICoKICoJYmFzZWQgb24gRXJpYyBZb3VuZGFsZSdzIHBlLXRlc3QgYW5kOgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KLyogTm90ZXM6CiAqIEJlZm9yZSB5b3Ugc3RhcnQgY2hhbmdpbmcgc29tZXRoaW5nIGluIHRoaXMgZmlsZSBiZSBhd2FyZSBvZiB0aGUgZm9sbG93aW5nOgogKgogKiAtIFRoZXJlIGFyZSBzZXZlcmFsIGZ1bmN0aW9ucyBjYWxsZWQgcmVjdXJzaXZlbHkuIEluIGEgdmVyeSBzdWJ0bGUgYW5kCiAqICAgb2JzY3VyZSB3YXkuIERMTHMgY2FuIHJlZmVyZW5jZSBlYWNoIG90aGVyIHJlY3Vyc2l2ZWx5IGV0Yy4KICogLSBJZiB5b3Ugd2FudCB0byBlbmhhbmNlLCBzcGVlZCB1cCBvciBjbGVhbiB1cCBzb21ldGhpbmcgaW4gaGVyZSwgdGhpbmsKICogICB0d2ljZSBXSFkgaXQgaXMgaW1wbGVtZW50ZWQgaW4gdGhhdCBzdHJhbmdlIHdheS4gVGhlcmUgaXMgdXN1YWxseSBhIHJlYXNvbi4KICogICBUaG91Z2ggc29tZXRpbWVzIGl0IG1pZ2h0IGp1c3QgYmUgbGF6eW5lc3MgOykKICogLSBJbiBQRV9NYXBJbWFnZSwgcmlnaHQgYmVmb3JlIFBFX2ZpeHVwX2ltcG9ydHMoKSBhbGwgZXh0ZXJuYWwgYW5kIGludGVybmFsCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIm50ZGxsX21pc2MuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbjMyKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCmlubGluZSBzdGF0aWMgdm9pZCAqZ2V0X3J2YSggSE1PRFVMRSBtb2R1bGUsIERXT1JEIHZhICkKewogICAgcmV0dXJuICh2b2lkICopKChjaGFyICopbW9kdWxlICsgdmEpOwp9CgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7CiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgV09SRAkJKm9yZGluYWw7CiAgRFdPUkQJCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIERXT1JEICpuYW1lOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHM7CiAgRFdPUkQgcnZhX3N0YXJ0LCBzaXplOwoKICBwZV9leHBvcnRzID0gUnRsSW1hZ2VEaXJlY3RvcnlFbnRyeVRvRGF0YSggaE1vZHVsZSwgVFJVRSwgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVCwgJnNpemUgKTsKICBydmFfc3RhcnQgPSAoY2hhciAqKXBlX2V4cG9ydHMgLSAoY2hhciAqKWhNb2R1bGU7CgogIE1vZHVsZSA9IGdldF9ydmEoaE1vZHVsZSwgcGVfZXhwb3J0cy0+TmFtZSk7CiAgRFBSSU5URigiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgRFBSSU5URigiTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwKICAgICAgICAgIE1vZHVsZSwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsID0gZ2V0X3J2YShoTW9kdWxlLCBwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucyA9IGZ1bmN0aW9uID0gZ2V0X3J2YShoTW9kdWxlLCBwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWUgPSBnZXRfcnZhKGhNb2R1bGUsIHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgRFBSSU5URigiIE9yZCAgICBSVkEgICAgIEFkZHIgICBOYW1lXG4iICk7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyssIGZ1bmN0aW9uKyspCiAgewogICAgICBpZiAoISpmdW5jdGlvbikgY29udGludWU7ICAvKiBObyBzdWNoIGZ1bmN0aW9uICovCiAgICAgIERQUklOVEYoICIlNGxkICUwOGx4ICVwIiwgaSArIHBlX2V4cG9ydHMtPkJhc2UsICpmdW5jdGlvbiwgZ2V0X3J2YShoTW9kdWxlLCAqZnVuY3Rpb24pICk7CiAgICAgIC8qIENoZWNrIGlmIHdlIGhhdmUgYSBuYW1lIGZvciBpdCAqLwogICAgICBmb3IgKGogPSAwOyBqIDwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaisrKQogICAgICAgICAgaWYgKG9yZGluYWxbal0gPT0gaSkKICAgICAgICAgIHsKICAgICAgICAgICAgICBEUFJJTlRGKCAiICAlcyIsIChjaGFyKilnZXRfcnZhKGhNb2R1bGUsIG5hbWVbal0pICk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgIGlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfc3RhcnQgKyBzaXplKSkKCSAgRFBSSU5URigiIChmb3J3YXJkZWQgLT4gJXMpIiwgKGNoYXIgKilnZXRfcnZhKGhNb2R1bGUsICpmdW5jdGlvbikpOwogICAgICBEUFJJTlRGKCJcbiIpOwogIH0KfQoKLyogTG9vayB1cCB0aGUgc3BlY2lmaWVkIGZ1bmN0aW9uIG9yIG9yZGluYWwgaW4gdGhlIGV4cG9ydCBsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgbmFtZSBsaXN0LgogKgktIGxvb2sgdXAgdGhlIG9yZGluYWwgd2l0aCB0aGF0IGluZGV4LgogKgktIHVzZSB0aGUgb3JkaW5hbCBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqIElmIGl0IGlzIGFuIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbiBsaXN0CiAqLwpzdGF0aWMgRkFSUFJPQyBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbigKCVdJTkVfTU9EUkVGICp3bSwJLyogW2luXSBXSU5FIG1vZHJlZmVyZW5jZSAqLwoJTFBDU1RSIGZ1bmNOYW1lLAkvKiBbaW5dIGZ1bmN0aW9uIG5hbWUgKi8KICAgICAgICBpbnQgaGludCwKICAgICAgICBCT09MIHNub29wICkKewoJV09SRAkJCQkqIG9yZGluYWxzOwoJRFdPUkQJCQkJKiBmdW5jdGlvbjsKCWludAkJCQlpLCBvcmRpbmFsOwoJRFdPUkQJCQkJcnZhX3N0YXJ0LCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CiAgICAgICAgRFdPUkQgKm5hbWU7CiAgICAgICAgY2hhciAqZW5hbWUgPSBOVUxMOwogICAgICAgIEZBUlBST0MgcHJvYzsKICAgICAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpleHBvcnRzOwogICAgICAgIERXT1JEIGV4cF9zaXplOwoKICAgICAgICBpZiAoIShleHBvcnRzID0gUnRsSW1hZ2VEaXJlY3RvcnlFbnRyeVRvRGF0YSggd20tPm1vZHVsZSwgVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVCwgJmV4cF9zaXplICkpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgaWYgKEhJV09SRChmdW5jTmFtZSkpIFRSQUNFKCIoJXMpXG4iLGZ1bmNOYW1lKTsKICAgICAgICBlbHNlIFRSQUNFKCIoJWQpXG4iLExPV09SRChmdW5jTmFtZSkpOwoKCW9yZGluYWxzPSBnZXRfcnZhKHdtLT5tb2R1bGUsIGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gZ2V0X3J2YSh3bS0+bW9kdWxlLCBleHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwoJbmFtZSAgICA9IGdldF9ydmEod20tPm1vZHVsZSwgZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CiAgICAgICAgcnZhX3N0YXJ0ID0gKGNoYXIgKilleHBvcnRzIC0gKGNoYXIgKil3bS0+bW9kdWxlOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQogICAgICAgIHsKICAgICAgICAgICAgaW50IG1pbiA9IDAsIG1heCA9IGV4cG9ydHMtPk51bWJlck9mTmFtZXMgLSAxOwoKICAgICAgICAgICAgLyogZmlyc3QgY2hlY2sgdGhlIGhpbnQgKi8KICAgICAgICAgICAgaWYgKGhpbnQgPj0gMCAmJiBoaW50IDw9IG1heCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5hbWUgPSBnZXRfcnZhKHdtLT5tb2R1bGUsIG5hbWVbaGludF0pOwogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoIGVuYW1lLCBmdW5jTmFtZSApKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG9yZGluYWwgPSBvcmRpbmFsc1toaW50XTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiB0aGVuIGRvIGEgYmluYXJ5IHNlYXJjaCAqLwogICAgICAgICAgICB3aGlsZSAobWluIDw9IG1heCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IHJlcywgcG9zID0gKG1pbiArIG1heCkgLyAyOwogICAgICAgICAgICAgICAgZW5hbWUgPSBnZXRfcnZhKHdtLT5tb2R1bGUsIG5hbWVbcG9zXSk7CiAgICAgICAgICAgICAgICBpZiAoIShyZXMgPSBzdHJjbXAoIGVuYW1lLCBmdW5jTmFtZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbcG9zXTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHJlcyA+IDApIG1heCA9IHBvcyAtIDE7CiAgICAgICAgICAgICAgICBlbHNlIG1pbiA9IHBvcyArIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIE5VTEw7Cgl9CiAgICAgICAgZWxzZSAgLyogZmluZCBieSBvcmRpbmFsICovCiAgICAgICAgewogICAgICAgICAgICBvcmRpbmFsID0gTE9XT1JEKGZ1bmNOYW1lKSAtIGV4cG9ydHMtPkJhc2U7CiAgICAgICAgICAgIGlmIChzbm9vcCAmJiBuYW1lKSAgLyogbmVlZCB0byBmaW5kIGEgbmFtZSBmb3IgaXQgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykKICAgICAgICAgICAgICAgICAgICBpZiAob3JkaW5hbHNbaV0gPT0gb3JkaW5hbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVuYW1lID0gZ2V0X3J2YSh3bS0+bW9kdWxlLCBuYW1lW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9Cgl9CgogZm91bmQ6CiAgICAgICAgaWYgKG9yZGluYWwgPj0gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiCW9yZGluYWwgJWxkIG91dCBvZiByYW5nZSFcbiIsIG9yZGluYWwgKyBleHBvcnRzLT5CYXNlICk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBhZGRyID0gZnVuY3Rpb25bb3JkaW5hbF07CiAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKCiAgICAgICAgcHJvYyA9IGdldF9ydmEod20tPm1vZHVsZSwgYWRkcik7CiAgICAgICAgaWYgKCgoY2hhciAqKXByb2MgPCAoY2hhciAqKWV4cG9ydHMpIHx8ICgoY2hhciAqKXByb2MgPj0gKGNoYXIgKilleHBvcnRzICsgZXhwX3NpemUpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHNub29wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWVuYW1lKSBlbmFtZSA9ICJAIjsKICAgICAgICAgICAgICAgIHByb2MgPSBTTk9PUF9HZXRQcm9jQWRkcmVzcyh3bS0+bW9kdWxlLGVuYW1lLG9yZGluYWwscHJvYyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHByb2M7CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIGZvcndhcmQgZW50cnkgcG9pbnQgKi8KICAgICAgICB7CiAgICAgICAgICAgICAgICBXSU5FX01PRFJFRiAqd21fZnc7CiAgICAgICAgICAgICAgICBjaGFyICpmb3J3YXJkID0gKGNoYXIgKilwcm9jOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIGlmIChlbmQgLSBmb3J3YXJkID49IHNpemVvZihtb2R1bGUpKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIG1lbWNweSggbW9kdWxlLCBmb3J3YXJkLCBlbmQgLSBmb3J3YXJkICk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoISh3bV9mdyA9IE1PRFVMRV9GaW5kTW9kdWxlKCBtb2R1bGUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJtb2R1bGUgbm90IGZvdW5kIGZvciBmb3J3YXJkICclcycgdXNlZCBieSAnJXMnXG4iLCBmb3J3YXJkLCB3bS0+bW9kbmFtZSApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgfQoJCWlmICghKHByb2MgPSBNT0RVTEVfR2V0UHJvY0FkZHJlc3MoIHdtX2Z3LT5tb2R1bGUsIGVuZCArIDEsIC0xLCBzbm9vcCApKSkKICAgICAgICAgICAgICAgICAgICBFUlIoImZ1bmN0aW9uIG5vdCBmb3VuZCBmb3IgZm9yd2FyZCAnJXMnIHVzZWQgYnkgJyVzJy4gSWYgeW91IGFyZSB1c2luZyBidWlsdGluICclcycsIHRyeSB1c2luZyB0aGUgbmF0aXZlIG9uZSBpbnN0ZWFkLlxuIiwgZm9yd2FyZCwgd20tPm1vZG5hbWUsIHdtLT5tb2RuYW1lICk7CgkJcmV0dXJuIHByb2M7Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAlQRV9maXh1cF9pbXBvcnRzCiAqLwpEV09SRCBQRV9maXh1cF9pbXBvcnRzKCBXSU5FX01PRFJFRiAqd20gKQp7CiAgICBpbnQgaSxjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uPTE7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqaW1wb3J0cywgKnBlX2ltcDsKICAgIERXT1JEIHNpemU7CgogICAgaW1wb3J0cyA9IFJ0bEltYWdlRGlyZWN0b3J5RW50cnlUb0RhdGEoIHdtLT5tb2R1bGUsIFRSVUUsIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlQsICZzaXplICk7CgogICAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICAgIHBlX2ltcCA9IGltcG9ydHM7CiAgICBpZiAoIXBlX2ltcCkgcmV0dXJuIDA7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0UoIkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgICAvKiBXZSBhc3N1bWUgdGhhdCB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBpbXBvcnQgd2l0aCAhMCBjaGFyYWN0ZXJpc3RpY3MgYW5kCiAgICAgKiBkZXRlY3QgYnJva2VuIGltcG9ydHMgd2l0aCBhbGwgY2hhcmFjdGVyaXN0aWNzIDAgKG5vdGFibHkgQm9ybGFuZCkgYW5kCiAgICAgKiBzd2l0Y2ggdGhlIGRldGVjdGlvbiBvZmYgZm9yIHRoZW0uCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CglpZiAoIWkgJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiA9IDA7CglpZiAoY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQlicmVhazsKCWkrKzsKICAgIH0KICAgIGlmICghaSkgcmV0dXJuIDA7ICAvKiBubyBpbXBvcnRzICovCgogICAgLyogQWxsb2NhdGUgbW9kdWxlIGRlcGVuZGVuY3kgbGlzdCAqLwogICAgd20tPm5EZXBzID0gaTsKICAgIHdtLT5kZXBzICA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaSpzaXplb2YoV0lORV9NT0RSRUYgKikgKTsKCiAgICAvKiBsb2FkIHRoZSBpbXBvcnRlZCBtb2R1bGVzLiBUaGV5IGFyZSBhdXRvbWF0aWNhbGx5CiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBpbXBvcnRzOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewogICAgCVdJTkVfTU9EUkVGCQkqd21JbXA7CglJTUFHRV9JTVBPUlRfQllfTkFNRQkqcGVfbmFtZTsKCVBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CiAJY2hhcgkJCSpuYW1lID0gZ2V0X3J2YSh3bS0+bW9kdWxlLCBwZV9pbXAtPk5hbWUpOwoKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoKCXdtSW1wID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXhBKCBuYW1lLCAwLCAwICk7CglpZiAoIXdtSW1wKSB7CiAgICAgICAgICAgIGlmKEdldExhc3RFcnJvcigpID09IEVSUk9SX0ZJTEVfTk9UX0ZPVU5EKQogICAgICAgICAgICAgICAgRVJSXyhtb2R1bGUpKCJNb2R1bGUgKGZpbGUpICVzICh3aGljaCBpcyBuZWVkZWQgYnkgJXMpIG5vdCBmb3VuZFxuIiwgbmFtZSwgd20tPmZpbGVuYW1lKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgRVJSXyhtb2R1bGUpKCJMb2FkaW5nIG1vZHVsZSAoZmlsZSkgJXMgKHdoaWNoIGlzIG5lZWRlZCBieSAlcykgZmFpbGVkIChlcnJvciAlbGQpLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgd20tPmZpbGVuYW1lLCBHZXRMYXN0RXJyb3IoKSk7CgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgICAgd20tPmRlcHNbaSsrXSA9IHdtSW1wOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0UoIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0gZ2V0X3J2YSh3bS0+bW9kdWxlLCAoRFdPUkQpcGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IGdldF9ydmEod20tPm1vZHVsZSwgKERXT1JEKXBlX2ltcC0+Rmlyc3RUaHVuayk7CgoJICAgIHdoaWxlIChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSgiLS0tIE9yZGluYWwgJXMsJWRcbiIsIG5hbWUsIG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oUERXT1JEKU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgKExQQ1NUUilvcmRpbmFsLCAtMSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIG9yZGluYWwsIHdtLT5maWxlbmFtZSApOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gZ2V0X3J2YSh3bS0+bW9kdWxlLCAoRFdPUkQpaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIHBlX25hbWUtPk5hbWUsIHBlX25hbWUtPkhpbnQsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcykgaW1wb3J0ZWQgZnJvbSAlcywgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxwZV9uYW1lLT5IaW50LHBlX25hbWUtPk5hbWUsd20tPmZpbGVuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoUERXT1JEKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIFRSQUNFKCJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IGdldF9ydmEod20tPm1vZHVsZSwgKERXT1JEKXBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSgiLS0tIE9yZGluYWwgJXMuJWRcbiIsbmFtZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpIG9yZGluYWwsIC0xLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQgaW1wb3J0ZWQgZnJvbSAlcywgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsLCB3bS0+ZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9Z2V0X3J2YSh3bS0+bW9kdWxlLCAoRFdPUkQpdGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsbmFtZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIHBlX25hbWUtPk5hbWUsIHBlX25hbWUtPkhpbnQsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCSAgICAJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIHBlX25hbWUtPkhpbnQsIHBlX25hbWUtPk5hbWUsIHdtLT5maWxlbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKFBEV09SRCkweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICoKICogVW5sdWNraWx5IHdlIGNhbid0IGp1c3QgbW1hcCB0aGUgc2VjdGlvbnMgd2hlcmUgd2Ugd2FudCB0aGVtLCBmb3IKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFIHBvaW50cyB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpITU9EVUxFIFBFX0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIERXT1JEIGZsYWdzICkKewogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBITU9EVUxFIGhNb2R1bGU7CiAgICBIQU5ETEUgbWFwcGluZzsKICAgIHZvaWQgKmJhc2U7CgogICAgVFJBQ0VfKG1vZHVsZSkoICJsb2FkaW5nICVzXG4iLCBmaWxlbmFtZSApOwoKICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ0EoIGhGaWxlLCBOVUxMLCBTRUNfSU1BR0UsIDAsIDAsIE5VTEwgKTsKICAgIGlmICghbWFwcGluZykgcmV0dXJuIDA7CiAgICBiYXNlID0gTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghYmFzZSkgcmV0dXJuIDA7CgogICAgLyogdmlydXMgY2hlY2sgKi8KCiAgICBoTW9kdWxlID0gKEhNT0RVTEUpYmFzZTsKICAgIG50ID0gUnRsSW1hZ2VOdEhlYWRlciggaE1vZHVsZSApOwoKICAgIGlmIChudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgIHsKICAgICAgICBpZiAoIVJ0bEltYWdlUnZhVG9TZWN0aW9uKCBudCwgaE1vZHVsZSwgbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKSkKICAgICAgICAgICAgTUVTU0FHRSgiVklSVVMgV0FSTklORzogUEUgbW9kdWxlIGhhcyBhbiBpbnZhbGlkIGVudHJ5cG9pbnQgKDB4JTA4bHgpICIKICAgICAgICAgICAgICAgICAgICAib3V0c2lkZSBhbGwgc2VjdGlvbnMgKHBvc3NpYmx5IGluZmVjdGVkIGJ5IFRjaGVybm9ieWwvU3BhY2VGaWxsZXIgdmlydXMpIVxuIiwKICAgICAgICAgICAgICAgICAgICBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCApOwogICAgfQoKICAgIHJldHVybiBoTW9kdWxlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAgUEVfQ3JlYXRlTW9kdWxlCiAqCiAqIENyZWF0ZSBXSU5FX01PRFJFRiBzdHJ1Y3R1cmUgZm9yIGxvYWRlZCBITU9EVUxFLCBsaW5rIGl0IGludG8KICogcHJvY2VzcyBtb2RyZWZfbGlzdCwgYW5kIGZpeHVwIGFsbCBpbXBvcnRzLgogKgogKiBOb3RlOiBoTW9kdWxlIG11c3QgcG9pbnQgdG8gYSBjb3JyZWN0bHkgYWxsb2NhdGVkIFBFIGltYWdlLAogKiAgICAgICB3aXRoIGJhc2UgcmVsb2NhdGlvbnMgYXBwbGllZDsgdGhlIDE2LWJpdCBkdW1teSBtb2R1bGUKICogICAgICAgYXNzb2NpYXRlZCB0byBoTW9kdWxlIG11c3QgYWxyZWFkeSBleGlzdC4KICoKICogTm90ZTogVGhpcyByb3V0aW5lIG11c3QgYWx3YXlzIGJlIGNhbGxlZCBpbiB0aGUgY29udGV4dCBvZiB0aGUKICogICAgICAgcHJvY2VzcyB0aGF0IGlzIHRvIG93biB0aGUgbW9kdWxlIHRvIGJlIGNyZWF0ZWQuCiAqCiAqIE5vdGU6IEFzc3VtZXMgdGhhdCB0aGUgcHJvY2VzcyBjcml0aWNhbCBzZWN0aW9uIGlzIGhlbGQKICovCldJTkVfTU9EUkVGICpQRV9DcmVhdGVNb2R1bGUoIEhNT0RVTEUgaE1vZHVsZSwgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFIGhGaWxlLCBCT09MIGJ1aWx0aW4gKQp7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudDsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnQgPSBOVUxMOwogICAgV0lORV9NT0RSRUYgKndtOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKCiAgICAvKiBSZXRyaWV2ZSBEYXRhRGlyZWN0b3J5IGVudHJpZXMgKi8KCiAgICBudCA9IFJ0bEltYWdlTnRIZWFkZXIoaE1vZHVsZSk7CiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUOwogICAgaWYgKGRpci0+U2l6ZSkgcGVfZXhwb3J0ID0gZ2V0X3J2YShoTW9kdWxlLCBkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0MgaGFuZGxlZCBpbiBQRV9Mb2FkSW1hZ2UgKi8KICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRyBoYW5kbGVkIGJ5IGRlYnVnZ2VyICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFMgaGFuZGxlZCBpbiBQRV9UbHNJbml0ICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUxBWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgewogICAgICAgIFRSQUNFKCJEZWxheWVkIGltcG9ydCwgc3R1YiBjYWxscyBMb2FkTGlicmFyeVxuIiApOwogICAgICAgIC8qCiAgICAgICAgICogTm90aGluZyB0byBkbyBoZXJlLgogICAgICAgICAqLwoKI2lmZGVmIEltZ0RlbGF5RGVzY3IKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgY29kZSBpcyB1c2VmdWwgdG8gb2JzZXJ2ZSB3aGF0IHRoZSBoZWNrIGlzIGdvaW5nIG9uLgogICAgICAgICAqLwogICAgICAgIHsKICAgICAgICAgICAgSW1nRGVsYXlEZXNjciAqcGVfZGVsYXkgPSBOVUxMOwogICAgICAgICAgICBwZV9kZWxheSA9IGdldF9ydmEoaE1vZHVsZSwgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgICAgIFRSQUNFKCJwZV9kZWxheS0+Z3JBdHRycyA9ICUwOHhcbiIsIHBlX2RlbGF5LT5nckF0dHJzKTsKICAgICAgICAgICAgVFJBQ0UoInBlX2RlbGF5LT5zek5hbWUgPSAlc1xuIiwgcGVfZGVsYXktPnN6TmFtZSk7CiAgICAgICAgICAgIFRSQUNFKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgICAgICBUUkFDRSgicGVfZGVsYXktPnBJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElBVCk7CiAgICAgICAgICAgIFRSQUNFKCJwZV9kZWxheS0+cElOVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wSU5UKTsKICAgICAgICAgICAgVFJBQ0UoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICAgICAgVFJBQ0UoInBlX2RlbGF5LT5wVW5sb2FkSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBVbmxvYWRJQVQpOwogICAgICAgICAgICBUUkFDRSgicGVfZGVsYXktPmR3VGltZVN0YW1wID0gJTA4eFxuIiwgcGVfZGVsYXktPmR3VGltZVN0YW1wKTsKICAgICAgICB9CiNlbmRpZiAvKiBJbWdEZWxheURlc2NyICovCiAgICB9CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPTV9ERVNDUklQVE9SOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeSsxNTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iICk7CgogICAgLyogQ3JlYXRlIDE2LWJpdCBkdW1teSBtb2R1bGUgKi8KCiAgICBpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggZmlsZW5hbWUsIGhNb2R1bGUgKSkgPCAzMikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIChEV09SRCloTW9kdWxlMTYgKTsJLyogVGhpcyBzaG91bGQgZ2l2ZSB0aGUgY29ycmVjdCBlcnJvciAqLwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qIEFsbG9jYXRlIGFuZCBmaWxsIFdJTkVfTU9EUkVGICovCgogICAgaWYgKCEod20gPSBNT0RVTEVfQWxsb2NNb2RSZWYoIGhNb2R1bGUsIGZpbGVuYW1lICkpKQogICAgewogICAgICAgIEZyZWVMaWJyYXJ5MTYoIGhNb2R1bGUxNiApOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgd20tPmhEdW1teU1vZCA9IGhNb2R1bGUxNjsKCiAgICBpZiAoIGJ1aWx0aW4gKQogICAgewogICAgICAgIE5FX01PRFVMRSAqcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgICAgIHBNb2R1bGUtPmZsYWdzIHw9IE5FX0ZGTEFHU19CVUlMVElOOwogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIH0KICAgIGVsc2UgaWYgKCBmbGFncyAmIERPTlRfUkVTT0xWRV9ETExfUkVGRVJFTkNFUyApCiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTOwoKICAgIHdtLT5maW5kX2V4cG9ydCA9IFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uOwoKICAgIC8qIER1bXAgRXhwb3J0cyAqLwoKICAgIGlmIChwZV9leHBvcnQgJiYgVFJBQ0VfT04od2luMzIpKQogICAgICAgIGR1bXBfZXhwb3J0cyggaE1vZHVsZSApOwoKICAgIC8qIEZpeHVwIEltcG9ydHMgKi8KCiAgICBpZiAoISh3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUykgJiYKICAgICAgICBQRV9maXh1cF9pbXBvcnRzKCB3bSApKQogICAgewogICAgICAgIC8qIHJlbW92ZSBlbnRyeSBmcm9tIG1vZHJlZiBjaGFpbiAqLwoKICAgICAgICBpZiAoICF3bS0+cHJldiApCiAgICAgICAgICAgIE1PRFVMRV9tb2RyZWZfbGlzdCA9IHdtLT5uZXh0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgd20tPnByZXYtPm5leHQgPSB3bS0+bmV4dDsKCiAgICAgICAgaWYgKCB3bS0+bmV4dCApIHdtLT5uZXh0LT5wcmV2ID0gd20tPnByZXY7CiAgICAgICAgd20tPm5leHQgPSB3bS0+cHJldiA9IE5VTEw7CgogICAgICAgIC8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKICAgICAgICAgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQogICAgICAgICAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCiAgICAgICAgICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSB0aGVtIGx5aW5nCiAgICAgICAgICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUuCiAgICAgICAgICogQXMgdGhlc2UgbWlnaHQgcmVmZXJlbmNlIG91ciB3bSwgd2UgZG9uJ3QgZnJlZSBpdC4KICAgICAgICAgKi8KICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKCFidWlsdGluICYmIHBlX2V4cG9ydCkKICAgICAgICBTTk9PUF9SZWdpc3RlckRMTCggaE1vZHVsZSwgd20tPm1vZG5hbWUsIHBlX2V4cG9ydC0+QmFzZSwgcGVfZXhwb3J0LT5OdW1iZXJPZkZ1bmN0aW9ucyApOwoKICAgIC8qIFNlbmQgRExMIGxvYWQgZXZlbnQgKi8KICAgIC8qIHdlIGRvbid0IG5lZWQgdG8gc2VuZCBhIGRsbCBldmVudCBmb3IgdGhlIG1haW4gZXhlICovCgogICAgaWYgKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKQogICAgewogICAgICAgIGlmIChoRmlsZSkKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgZHJpdmVfdHlwZSA9IEdldERyaXZlVHlwZUEoIHdtLT5zaG9ydF9maWxlbmFtZSApOwogICAgICAgICAgICAvKiBkb24ndCBrZWVwIHRoZSBmaWxlIGhhbmRsZSBvcGVuIG9uIHJlbW92YWJsZSBtZWRpYSAqLwogICAgICAgICAgICBpZiAoZHJpdmVfdHlwZSA9PSBEUklWRV9SRU1PVkFCTEUgfHwgZHJpdmVfdHlwZSA9PSBEUklWRV9DRFJPTSkgaEZpbGUgPSAwOwogICAgICAgIH0KICAgICAgICBTRVJWRVJfU1RBUlRfUkVRKCBsb2FkX2RsbCApCiAgICAgICAgewogICAgICAgICAgICByZXEtPmhhbmRsZSAgICAgPSBoRmlsZTsKICAgICAgICAgICAgcmVxLT5iYXNlICAgICAgID0gKHZvaWQgKiloTW9kdWxlOwogICAgICAgICAgICByZXEtPnNpemUgICAgICAgPSBudC0+T3B0aW9uYWxIZWFkZXIuU2l6ZU9mSW1hZ2U7CiAgICAgICAgICAgIHJlcS0+ZGJnX29mZnNldCA9IG50LT5GaWxlSGVhZGVyLlBvaW50ZXJUb1N5bWJvbFRhYmxlOwogICAgICAgICAgICByZXEtPmRiZ19zaXplICAgPSBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlN5bWJvbHM7CiAgICAgICAgICAgIHJlcS0+bmFtZSAgICAgICA9ICZ3bS0+ZmlsZW5hbWU7CiAgICAgICAgICAgIHdpbmVfc2VydmVyX2FkZF9kYXRhKCByZXEsIHdtLT5maWxlbmFtZSwgc3RybGVuKHdtLT5maWxlbmFtZSkgKTsKICAgICAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgfQoKICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KV0lORV9NT0RSRUYgKlBFX0xvYWRMaWJyYXJ5RXhBIChMUENTVFIgbmFtZSwgRFdPUkQgZmxhZ3MpCnsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCVdJTkVfTU9EUkVGCSp3bTsKCUhBTkRMRQkJaEZpbGU7CgoJaEZpbGUgPSBDcmVhdGVGaWxlQSggbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwoJaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwoKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBmbGFncyApOwoJaWYgKCFoTW9kdWxlMzIpCgl7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBoTW9kdWxlMzIsIG5hbWUsIGZsYWdzLCBoRmlsZSwgRkFMU0UgKSkgKQoJewoJCUVSUiggImNhbid0IGxvYWQgJXNcbiIsIG5hbWUgKTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCVNldExhc3RFcnJvciggRVJST1JfT1VUT0ZNRU1PUlkgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CglyZXR1cm4gd207Cn0KCgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3bHkgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwp0eXBlZGVmIERXT1JEIChDQUxMQkFDSyAqRExMRU5UUllQUk9DKShITU9EVUxFLERXT1JELExQVk9JRCk7CgpCT09MIFBFX0luaXRETEwoIEhNT0RVTEUgbW9kdWxlLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCApCnsKICAgIEJPT0wgcmV0diA9IFRSVUU7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFJ0bEltYWdlTnRIZWFkZXIobW9kdWxlKTsKCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmIChudCAmJiAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSkKICAgIHsKICAgICAgICBETExFTlRSWVBST0MgZW50cnkgPSAodm9pZCopKChjaGFyKiltb2R1bGUgKyBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCk7CiAgICAgICAgaWYgKFRSQUNFX09OKHJlbGF5KSkKICAgICAgICAgICAgRFBSSU5URigiJTA0bHg6Q2FsbCBQRSBETEwgKHByb2M9JXAsbW9kdWxlPSVwLHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFRocmVhZElkKCksIGVudHJ5LCBtb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgICAgICByZXR2ID0gZW50cnkoIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgICAgIGlmIChUUkFDRV9PTihyZWxheSkpCiAgICAgICAgICAgIERQUklOVEYoIiUwNGx4OlJldCAgUEUgRExMIChwcm9jPSVwLG1vZHVsZT0lcCx0eXBlPSVsZCxyZXM9JXApIHJldHZhbD0leFxuIiwKICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50VGhyZWFkSWQoKSwgZW50cnksIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCwgcmV0diApOwogICAgfQoKICAgIHJldHVybiByZXR2Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kc3RhdGljIExQVk9JRApfZml4dXBfYWRkcmVzcyhQSU1BR0VfT1BUSU9OQUxfSEVBREVSIG9wdCxpbnQgZGVsdGEsTFBWT0lEIGFkZHIpIHsKCWlmICgJKChEV09SRClhZGRyPm9wdC0+SW1hZ2VCYXNlKSAmJgoJCSgoRFdPUkQpYWRkcjxvcHQtPkltYWdlQmFzZStvcHQtPlNpemVPZkltYWdlKQoJKQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBub3QgYmVlbiByZWxvY2F0ZWQhICovCgkJcmV0dXJuIChMUFZPSUQpKCgoRFdPUkQpYWRkcikrZGVsdGEpOwoJZWxzZQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBiZWVuIHJlbG9jYXRlZCBhbHJlYWR5ICovCgkJcmV0dXJuIGFkZHI7Cn0Kdm9pZCBQRV9Jbml0VGxzKCB2b2lkICkKewoJV0lORV9NT0RSRUYJCSp3bTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZSxkaXJzaXplOwoJTFBWT0lECQkJbWVtOwoJUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKICAgICAgICBpbnQgZGVsdGE7CgoJZm9yICh3bSA9IE1PRFVMRV9tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkgewogICAgICAgICAgICAgICAgcGVoID0gUnRsSW1hZ2VOdEhlYWRlcih3bS0+bW9kdWxlKTsKICAgICAgICAgICAgICAgIHBkaXIgPSBSdGxJbWFnZURpcmVjdG9yeUVudHJ5VG9EYXRhKCB3bS0+bW9kdWxlLCBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFMsICZkaXJzaXplICk7CiAgICAgICAgICAgICAgICBpZiAoIXBkaXIpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgZGVsdGEgPSAoY2hhciAqKXdtLT5tb2R1bGUgLSAoY2hhciAqKXBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoKCQlpZiAoIHdtLT50bHNpbmRleCA9PSAtMSApIHsKCQkJTFBEV09SRCB4YWRkcjsKCQkJd20tPnRsc2luZGV4ID0gVGxzQWxsb2MoKTsKCQkJeGFkZHIgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLAoJCQkJCXBkaXItPkFkZHJlc3NPZkluZGV4CgkJCSk7CgkJCSp4YWRkcj13bS0+dGxzaW5kZXg7CgkJfQoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsKExQVk9JRClwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEpLGRhdGFzaXplKTsKCQlpZiAocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKSB7CgkJICAgICBQSU1BR0VfVExTX0NBTExCQUNLICpjYnM7CgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHdtLT50bHNpbmRleCwgbWVtICk7Cgl9Cn0K