| 544 | |
| 545 | template<offset_hash_pair OHP, class T> |
| 546 | struct lazy_function : lazy_base<lazy_function<OHP, T>, T> { |
| 547 | using base_type = lazy_base<lazy_function<OHP, T>, T>; |
| 548 | |
| 549 | template<class... Args> |
| 550 | LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const |
| 551 | { |
| 552 | #ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS |
| 553 | return get()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...); |
| 554 | #else |
| 555 | return this->cached()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...); |
| 556 | #endif |
| 557 | } |
| 558 | |
| 559 | template<class F = T, class Enum = unsafe_module_enumerator> |
| 560 | LAZY_IMPORTER_FORCEINLINE static F get() noexcept |
| 561 | { |
| 562 | // for backwards compatability. |
| 563 | // Before 2.0 it was only possible to resolve forwarded exports when |
| 564 | // this macro was enabled |
| 565 | #ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS |
| 566 | return forwarded<F, Enum>(); |
| 567 | #else |
| 568 | |
| 569 | Enum e; |
| 570 | |
| 571 | do { |
| 572 | #ifdef LAZY_IMPORTER_HARDENED_MODULE_CHECKS |
| 573 | if(!e.value->DllBase || !e.value->FullDllName.Length) |
| 574 | continue; |
| 575 | #endif |
| 576 | |
| 577 | const exports_directory exports(e.value->DllBase); |
| 578 | |
| 579 | if(exports) { |
| 580 | auto export_index = exports.size(); |
| 581 | while(export_index--) |
| 582 | if(hash(exports.name(export_index), get_offset(OHP)) == get_hash(OHP)) |
| 583 | return (F)(exports.address(export_index)); |
| 584 | } |
| 585 | } while(e.next()); |
| 586 | return {}; |
| 587 | #endif |
| 588 | } |
| 589 | |
| 590 | template<class F = T, class Enum = unsafe_module_enumerator> |
| 591 | LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept |
| 592 | { |
| 593 | detail::win::UNICODE_STRING_T name; |
| 594 | forwarded_hashes hashes{ 0, get_hash(OHP) }; |
| 595 | |
| 596 | Enum e; |
| 597 | do { |
| 598 | name = e.value->BaseDllName; |
| 599 | name.Length -= 8; // get rid of .dll extension |
| 600 | |
| 601 | if(!hashes.module_hash || hash(name, get_offset(OHP)) == hashes.module_hash) { |
| 602 | const exports_directory exports(e.value->DllBase); |
| 603 |
nothing calls this directly
no outgoing calls
no test coverage detected