1 /* dllpstub.cpp: Help implement DLL proxies
2 * Copyright (c) 2005 Jochen Tucht
4 * License: This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 Please mind 2. a) of the GNU General Public License, and log your changes below.
20 DATE: BY: DESCRIPTION:
21 ========== ================== ================================================
22 2005/02/26 Jochen Tucht Created
23 2006/09/10 Kimmo Varis Don't use 'export' as variable name
24 Visual Studio 2005 warns about it.
33 * @brief Throw DLLPSTUB related exception.
35 void DLLPSTUB::Throw(LPCSTR name, HMODULE handle, DWORD dwError, bool bFreeLibrary)
37 CString strError = name;
38 if (handle != nullptr)
42 if (::GetModuleFileName(handle, module + 1, 4095) == 0)
44 wsprintf(module + 1, _T("%p"), handle);
46 strError += strError.IsEmpty() ? module + 1 : module;
49 if (CInternetException(dwError).GetErrorMessage(szError + 2, 510))
55 if (bFreeLibrary && handle != nullptr)
59 AfxThrowOleDispatchException(0, strError);
63 * @brief Load a dll and import a number of functions.
65 HMODULE DLLPSTUB::Load()
67 // DLLPSTUB assumes that it is embedded in its owner
68 // followed by a char array of the DLL name to load
69 // so it access the char array via *(this + 1)
70 LPCSTR *proxy = (LPCSTR *) (this + 1);
71 HMODULE handle = nullptr;
72 if (LPCSTR name = *proxy)
74 if (proxy[1] != nullptr && proxy[1] != name)
76 handle = LoadLibraryA(name);
77 if (handle != nullptr)
79 // If any of the version members are non-zero
80 // then we require that DLL export "DllGetVersion"
81 // and report a version as least as high as our
82 // version number members
83 if (dwMajorVersion || dwMinorVersion || dwBuildNumber)
85 // Is the DLL up to date?
87 dvi.cbSize = sizeof dvi;
88 dvi.dwMajorVersion = 0;
89 dvi.dwMinorVersion = 0;
90 dvi.dwBuildNumber = 0;
91 DLLGETVERSIONPROC DllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(handle, "DllGetVersion");
94 DllGetVersion == nullptr
95 || FAILED(DllGetVersion(&dvi))
97 dwMajorVersion && dvi.dwMajorVersion != dwMajorVersion
98 ? dvi.dwMajorVersion < dwMajorVersion :
99 dwMinorVersion && dvi.dwMinorVersion != dwMinorVersion
100 ? dvi.dwMinorVersion < dwMinorVersion :
101 dvi.dwBuildNumber < dwBuildNumber
105 // Well, that's the most appropriate canned system
106 // message I came across: If DLL is outdated, it may
107 // actually lack some interface we need...
108 Throw(0, handle, CO_S_NOTALLINTERFACES, true);
111 LPCSTR *pszExport = proxy;
113 while ((name = *++pszExport) != nullptr)
115 *pszExport = (LPCSTR)GetProcAddress(handle, name);
116 if (*pszExport == nullptr)
118 *proxy = proxy[1] = name;
119 pszExport = proxy + 2;
123 *pszExport = (LPCSTR)handle;
126 if ((name = *proxy) != nullptr)
128 DWORD dwError = ERROR_MOD_NOT_FOUND;
130 if (proxy[1] == name)
132 dwError = ERROR_PROC_NOT_FOUND;
133 handle1 = (HMODULE)proxy[2];
135 Throw(name, handle1, dwError, false);