aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-06-02 07:53:10 +0100
committerRon Yorston <rmy@pobox.com>2020-06-02 08:27:46 +0100
commit27c718aa1a4674587925adb543362cb8e60814c4 (patch)
treedb22579586cede7cb0f3351ce66c36f98a9a5a7a /win32
parent5ea460a32a9882906c7ee3656b8fb0dcdbce2abc (diff)
downloadbusybox-w32-27c718aa1a4674587925adb543362cb8e60814c4.tar.gz
busybox-w32-27c718aa1a4674587925adb543362cb8e60814c4.tar.bz2
busybox-w32-27c718aa1a4674587925adb543362cb8e60814c4.zip
win32: use lazy loading for certain DLLs
Only a handful of functions are used from shell32.dll, userenv.dll and psapi.dll. Mostly these functions are in out of the way places. By loading the functions only when required we can avoid the startup cost of linking the three DLLs in the common case that they aren't needed.
Diffstat (limited to 'win32')
-rw-r--r--win32/lazyload.h16
-rw-r--r--win32/mingw.c27
-rw-r--r--win32/process.c15
3 files changed, 36 insertions, 22 deletions
diff --git a/win32/lazyload.h b/win32/lazyload.h
index a9fcff209..034bc7e45 100644
--- a/win32/lazyload.h
+++ b/win32/lazyload.h
@@ -21,19 +21,7 @@ struct proc_addr {
21#define INIT_PROC_ADDR(dll, function) \ 21#define INIT_PROC_ADDR(dll, function) \
22 (function = get_proc_addr(#dll, #function, &proc_addr_##function)) 22 (function = get_proc_addr(#dll, #function, &proc_addr_##function))
23 23
24static inline void *get_proc_addr(const char *dll, const char *function, struct proc_addr *proc) 24void *get_proc_addr(const char *dll, const char *function,
25{ 25 struct proc_addr *proc);
26 /* only do this once */
27 if (!proc->initialized) {
28 HANDLE hnd = LoadLibraryExA(dll, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
29 if (hnd)
30 proc->pfunction = GetProcAddress(hnd, function);
31 proc->initialized = 1;
32 }
33 /* set ENOSYS if DLL or function was not found */
34 if (!proc->pfunction)
35 errno = ENOSYS;
36 return proc->pfunction;
37}
38 26
39#endif 27#endif
diff --git a/win32/mingw.c b/win32/mingw.c
index 5c4c39b9d..105b7864d 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -837,17 +837,17 @@ static char *gethomedir(void)
837 static char *buf = NULL; 837 static char *buf = NULL;
838 DWORD len = PATH_MAX; 838 DWORD len = PATH_MAX;
839 HANDLE h; 839 HANDLE h;
840 DECLARE_PROC_ADDR(BOOL, GetUserProfileDirectoryA, HANDLE, LPSTR, LPDWORD);
840 841
841 if (!buf) 842 if (buf)
842 buf = xzalloc(PATH_MAX);
843
844 if (buf[0])
845 return buf; 843 return buf;
846 844
845 buf = xzalloc(PATH_MAX);
847 if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h) ) 846 if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h) )
848 return buf; 847 return buf;
849 848
850 GetUserProfileDirectory(h, buf, &len); 849 if (INIT_PROC_ADDR(userenv.dll, GetUserProfileDirectoryA))
850 GetUserProfileDirectoryA(h, buf, &len);
851 CloseHandle(h); 851 CloseHandle(h);
852 return bs_to_slash(buf); 852 return bs_to_slash(buf);
853} 853}
@@ -1027,7 +1027,6 @@ int link(const char *oldpath, const char *newpath)
1027 LPSECURITY_ATTRIBUTES); 1027 LPSECURITY_ATTRIBUTES);
1028 1028
1029 if (!INIT_PROC_ADDR(kernel32.dll, CreateHardLinkA)) { 1029 if (!INIT_PROC_ADDR(kernel32.dll, CreateHardLinkA)) {
1030 errno = ENOSYS;
1031 return -1; 1030 return -1;
1032 } 1031 }
1033 if (!CreateHardLinkA(newpath, oldpath, NULL)) { 1032 if (!CreateHardLinkA(newpath, oldpath, NULL)) {
@@ -1767,3 +1766,19 @@ void make_sparse(int fd, off_t start, off_t end)
1767 DeviceIoControl(fh, FSCTL_SET_ZERO_DATA, &fzdi, sizeof(fzdi), 1766 DeviceIoControl(fh, FSCTL_SET_ZERO_DATA, &fzdi, sizeof(fzdi),
1768 NULL, 0, &dwTemp, NULL); 1767 NULL, 0, &dwTemp, NULL);
1769} 1768}
1769
1770void *get_proc_addr(const char *dll, const char *function,
1771 struct proc_addr *proc)
1772{
1773 /* only do this once */
1774 if (!proc->initialized) {
1775 HANDLE hnd = LoadLibraryExA(dll, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
1776 if (hnd)
1777 proc->pfunction = GetProcAddress(hnd, function);
1778 proc->initialized = 1;
1779 }
1780 /* set ENOSYS if DLL or function was not found */
1781 if (!proc->pfunction)
1782 errno = ENOSYS;
1783 return proc->pfunction;
1784}
diff --git a/win32/process.c b/win32/process.c
index 04775100b..5833a0323 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -446,6 +446,17 @@ static char *get_bb_string(DWORD pid, const char *exe, char *string)
446 char exepath[PATH_MAX]; 446 char exepath[PATH_MAX];
447 char *name = NULL; 447 char *name = NULL;
448 int i; 448 int i;
449 DECLARE_PROC_ADDR(DWORD, GetProcessImageFileNameA, HANDLE,
450 LPSTR, DWORD);
451 DECLARE_PROC_ADDR(BOOL, EnumProcessModules, HANDLE, HMODULE *,
452 DWORD, LPDWORD);
453 DECLARE_PROC_ADDR(DWORD, GetModuleFileNameExA, HANDLE, HMODULE,
454 LPSTR, DWORD);
455
456 if (!INIT_PROC_ADDR(psapi.dll, GetProcessImageFileNameA) ||
457 !INIT_PROC_ADDR(psapi.dll, EnumProcessModules) ||
458 !INIT_PROC_ADDR(psapi.dll, GetModuleFileNameExA))
459 return NULL;
449 460
450 if (!(proc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, 461 if (!(proc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
451 FALSE, pid))) { 462 FALSE, pid))) {
@@ -453,7 +464,7 @@ static char *get_bb_string(DWORD pid, const char *exe, char *string)
453 } 464 }
454 465
455 if (exe == NULL) { 466 if (exe == NULL) {
456 if (GetProcessImageFileName(proc, exepath, PATH_MAX) != 0) { 467 if (GetProcessImageFileNameA(proc, exepath, PATH_MAX) != 0) {
457 exe = bb_basename(exepath); 468 exe = bb_basename(exepath);
458 } 469 }
459 } 470 }
@@ -470,7 +481,7 @@ static char *get_bb_string(DWORD pid, const char *exe, char *string)
470 481
471 for (i=0; exe != NULL && i<needed/sizeof(HMODULE); ++i) { 482 for (i=0; exe != NULL && i<needed/sizeof(HMODULE); ++i) {
472 char modname[MAX_PATH]; 483 char modname[MAX_PATH];
473 if (GetModuleFileNameEx(proc, mlist[i], modname, sizeof(modname))) { 484 if (GetModuleFileNameExA(proc, mlist[i], modname, sizeof(modname))) {
474 if (strcasecmp(bb_basename(modname), exe) == 0) { 485 if (strcasecmp(bb_basename(modname), exe) == 0) {
475 break; 486 break;
476 } 487 }