2017-02-21 88 views
-1

我在64位Windows安裝Mozilla FireFox x64加載32位的DLL,現在我想LoadLibrary(mozglue.dll),但我收到錯誤號193如何在64位Windows

LoadLibrary(mozglue.dll)做工不錯的32位Windows與Mozilla FireFox 86

我使用此代碼:

#include <Windows.h> 
#include <strsafe.h> 

int main() 
{ 
    HMODULE hndl; 
    DWORD dwError = 0; 
    WCHAR errorBuff[MAX_PATH] = {}; 

    hndl = LoadLibraryW(L"C:\\Program Files\\Mozilla Firefox\\mozglue.dll"); 
    dwError = GetLastError(); 
    StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError); 
    MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK); 
    FreeLibrary(hndl); 

    return 0; 
} 

這段代碼有什麼問題?

編輯:

我使用:的

LoadLibraryExW(L"C:\\Program Files\\Mozilla Firefox\\mozglue.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);

代替:

LoadLibraryW(L"C:\\Program Files\\Mozilla Firefox\\mozglue.dll");

現在GetLastError返回0,但GetProcAddress失敗...

#include <Windows.h> 
    #include <strsafe.h> 


    typedef enum SECItemType { 
     siBuffer = 0, 
     siClearDataBuffer = 1, 
     siCipherDataBuffer, 
     siDERCertBuffer, 
     siEncodedCertBuffer, 
     siDERNameBuffer, 
     siEncodedNameBuffer, 
     siAsciiNameString, 
     siAsciiString, 
     siDEROID, 
     siUnsignedInteger, 
     siUTCTime, 
     siGeneralizedTime 
    }; 

    struct SECItem { 
     SECItemType type; 
     unsigned char *data; 
     size_t len; 
    }; 

    typedef enum SECStatus { 
     SECWouldBlock = -2, 
     SECFailure = -1, 
     SECSuccess = 0 
    }; 


    typedef struct PK11SlotInfoStr PK11SlotInfo; 
    typedef SECStatus(*NSS_Init) (const char *); 
    typedef SECStatus(*NSS_Shutdown) (void); 
    typedef PK11SlotInfo * (*PK11_GetInternalKeySlot) (void); 
    typedef void(*PK11_FreeSlot) (PK11SlotInfo *); 
    typedef SECStatus(*PK11_Authenticate) (PK11SlotInfo *, int, void *); 
    typedef SECStatus(*PK11SDR_Decrypt) (SECItem *, SECItem *, void *); 

    PK11_GetInternalKeySlot PK11GetInternalKeySlot; 
    PK11_FreeSlot PK11FreeSlot; 
    PK11_Authenticate PK11Authenticate; 
    PK11SDR_Decrypt PK11SDRDecrypt; 
    NSS_Init fpNSS_INIT; 
    NSS_Shutdown fpNSS_Shutdown; 



    BOOL loadFunc() 
    { 
     HMODULE hndl; 
     DWORD dwError = 0; 
     WCHAR errorBuff[MAX_PATH] = {}; 
     BOOL retVal = FALSE; 

     hndl = LoadLibraryExW(L"C:\\Program Files\\Mozilla Firefox\\mozglue.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); 
     dwError = GetLastError(); 
     StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError); 
     MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK); 


     hndl = LoadLibraryExW(L"C:\\Program Files\\Mozilla Firefox\\nss3.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); 
     dwError = GetLastError(); 
     StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError); 
     MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK); 

     if (hndl) 
     { 
      fpNSS_INIT = (NSS_Init)GetProcAddress(hndl, "NSS_Init"); 
      fpNSS_Shutdown = (NSS_Shutdown)GetProcAddress(hndl, "NSS_Shutdown"); 
      PK11GetInternalKeySlot = (PK11_GetInternalKeySlot)GetProcAddress(hndl, "PK11_GetInternalKeySlot"); 
      PK11FreeSlot = (PK11_FreeSlot)GetProcAddress(hndl, "PK11_FreeSlot"); 
      PK11Authenticate = (PK11_Authenticate)GetProcAddress(hndl, "PK11_Authenticate"); 
      PK11SDRDecrypt = (PK11SDR_Decrypt)GetProcAddress(hndl, "PK11SDR_Decrypt"); 
     } 
     return !(!fpNSS_INIT || !fpNSS_Shutdown || !PK11GetInternalKeySlot || !PK11Authenticate || !PK11SDRDecrypt || !PK11FreeSlot); 
    } 



    int main() 
    { 
     if (loadFunc()) 
     { 
      MessageBoxW(NULL, L"OK", L"", MB_OK); 
     } 
     else 
     { 
      MessageBoxW(NULL, L"NO", L"", MB_OK); 
     } 

     return 0; 
    } 
+0

你是如何編譯你的代碼的?你編譯過64位嗎?你在這裏安裝的mozglue最有可能是64位的Firefox,如果你的可執行文件是32位的,它不能加載它。 –

+1

您可以在64位Windows上將32位DLL加載到32位***進程***中,但無法將其加載到64位進程中。所以你必須安裝32位的Firefox。 –

+0

我編譯一次32位,一次64位,但都得到錯誤193 –

回答

0

您要麼嘗試將32位DLL加載到64位進程中,要麼將64位DLL加載到32位進程中。它不能做到。

我想如果你有'Mozilla FireFox x64'mozglue.dll是64位的 - 所以你需要編譯和鏈接你的測試程序爲64位。

+0

我知道,但我安裝了一個x64 Firefox,並且我嘗試加載的mozglue是安裝後創建的dll ... –

+1

那麼,dumpbin/dependency walker會說你的測試exe是(32位還是64位)位?),它說mozglue是什麼? –

+0

我編輯我的問題,請看看 –

0

您的第一個問題是,64位程序無法加載32位DLL,而32位程序無法加載64位DLL以執行代碼。這在MSDN的Process Interopability信息中描述:

您可以使用仿真層在64位Windows上運行基於Win32的應用程序。有關更多信息,請參閱運行32位應用程序。

在64位Windows上,64位進程無法加載32位動態鏈接庫(DLL)。此外,32位進程無法加載64位DLL。

如果您需要同時支持32位程序和64位,最簡單的方法是安裝32位版本的Mozilla DLL(通過32位Mozilla安裝),並且您也可以64位Mozilla。默認情況下,64位Mozilla應放置在C:\Program Files\Mozilla Firefox\和32位Mozilla中,位於C:\Program Files (x86)\Mozilla Firefox\。構建64位的應用程序時,VS的32位應用程序加載DLL時一樣mozglue.dll


你不檢查,看看是否hndl爲空或不是你需要考慮到不同的目錄。如果返回的句柄爲NULL,那麼只應檢查GetLastError,而不是NULL。其次調用LoadLibraryExWLOAD_LIBRARY_AS_DATAFILE允許您加載DLL資源,但不允許您使用GetProcAddress檢索函數地址。這是在MSDN文檔記錄的LoadLibraryEx

LOAD_LIBRARY_AS_DATAFILE 0x00000002

如果使用此值,系統中的文件到調用進程的虛擬地址空間映射,就好像它是一個數據文件。沒有任何事情可以執行或準備執行映射文件。因此,您無法使用此DLL調用諸如 GetModuleFileName,GetModuleHandle或GetProcAddress之類的函數。使用此值會導致寫入只讀內存以引發訪問衝突。當您只想加載DLL以從中提取消息或資源時,請使用此標誌。


保持思想上面記我與修訂loadfunc編譯你的代碼,並建立它作爲一個64位應用程序。當一個MessageBox完成了你的程序打印OK

BOOL loadFunc() 
{ 
    HMODULE hndl; 
    DWORD dwError = 0; 
    WCHAR errorBuff[MAX_PATH] = {}; 
    BOOL retVal = FALSE; 

    hndl = LoadLibraryW(L"C:\\Program Files\\Mozilla Firefox\\mozglue.dll"); 
    // if the handle is NULL then check for an error otherwise proceed 
    if (!hndl) 
    { 
     dwError = GetLastError(); 
     StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError); 
     MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK); 
     return TRUE; 
    } 

    hndl = LoadLibraryW(L"C:\\Program Files\\Mozilla Firefox\\nss3.dll"); 
    // if the handle is NOT NULL then try to retrieve the method addresses 
    if (hndl) 
    { 
     fpNSS_INIT = (NSS_Init)GetProcAddress(hndl, "NSS_Init"); 
     fpNSS_Shutdown = (NSS_Shutdown)GetProcAddress(hndl, "NSS_Shutdown"); 
     PK11GetInternalKeySlot = (PK11_GetInternalKeySlot)GetProcAddress(hndl, "PK11_GetInternalKeySlot"); 
     PK11FreeSlot = (PK11_FreeSlot)GetProcAddress(hndl, "PK11_FreeSlot"); 
     PK11Authenticate = (PK11_Authenticate)GetProcAddress(hndl, "PK11_Authenticate"); 
     PK11SDRDecrypt = (PK11SDR_Decrypt)GetProcAddress(hndl, "PK11SDR_Decrypt"); 
    } 
    // the handle was NULL if we get here so show the error 
    else 
    { 
     dwError = GetLastError(); 
     StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError); 
     MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK); 
     return TRUE; 
    } 
    return !(!fpNSS_INIT || !fpNSS_Shutdown || !PK11GetInternalKeySlot || !PK11Authenticate || !PK11SDRDecrypt || !PK11FreeSlot); 
} 

對於32位程序你需要如前面提到的改變路徑在上面的代碼爲32位的Mozilla目錄和編譯爲86 32位應用程序。對於前面提到的32位代碼的默認路徑是C:\Program Files (x86)\Mozilla Firefox\

我從這個download linkthis link 32位Mozilla安裝下載的Mozilla的64位版本。