1

我需要创建小 dll 来拦截简单的 mapi 调用并通过以下方式发送文件:

文件->作为附件发送到(在 excel、word、acrobat 阅读器中...)或通过资源管理器->右键菜单->发送到->邮件收件人

附加到 gmail。

读完后:

Mapi32.dll 存根注册表设置 (Windows)

Mapi32 存根库 (Windows)

并在 stackoverflow 和其他网站上搜索,我使用 code::blocks 创建了一个非常小的 dll,它向我显示了用于调查该过程的信息。

我已将它正确安装在注册表中,如 HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail\SimpMapi 上的先前链接所示。

我在我的 win xp pro 上的控制面板-> Internet 选项中选择了我的 SimpMapi 客户端。

当我打开 excel 写入一些单元格并转到 File->Send like attachment dll 显示我首先调用 MapiLogon,第二次调用 MapiSendMail,第三次在我关闭 excel 时调用 MapiLogoff,但随后它抛出错误并关闭 excel.exe。

如果我从资源管理器窗口尝试它,右键单击一个文件和 SendTo->Mail 收件人,它会直接调用 MapiSendMail,当我在 MsgBox 中单击 ok 时,它会引发错误并关闭 explorer.exe

你能帮我找出问题所在吗?

这是 mail.h 文件:

#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>

// Todo lo necesario a incluir por mapi.h
#define SUCCESS_SUCCESS         0
#define MAPI_E_USER_ABORT       1
#define MAPI_E_LOGIN_FAILURE    3

typedef unsigned long FLAGS;
typedef unsigned long LHANDLE;
typedef unsigned long FAR *LPLHANDLE, FAR *LPULONG;

typedef struct {
  ULONG ulReserved;
  ULONG ulRecipClass;
  LPSTR lpszName;
  LPSTR lpszAddress;
  ULONG ulEIDSize;
  LPVOID lpEntryID;
} MapiRecipDesc, *lpMapiRecipDesc;

typedef struct {
  ULONG ulReserved;
  ULONG flFlags;
  ULONG nPosition;
  LPSTR lpszPathName;
  LPSTR lpszFileName;
  LPVOID lpFileType;
} MapiFileDesc, *lpMapiFileDesc;

typedef struct {
  ULONG ulReserved;
  LPSTR lpszSubject;
  LPSTR lpszNoteText;
  LPSTR lpszMessageType;
  LPSTR lpszDateReceived;
  LPSTR lpszConversationID;
  FLAGS flFlags;
  lpMapiRecipDesc lpOriginator;
  ULONG nRecipCount;
  lpMapiRecipDesc lpRecips;
  ULONG nFileCount;
  lpMapiFileDesc lpFiles;
} MapiMessage, *lpMapiMessage;


/*  To use this exported function of dll, include this header
 *  in your project.
 */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

extern "C" void DLL_EXPORT SomeFunction(const LPCSTR sometext);

extern "C" ULONG DLL_EXPORT MAPILogon(ULONG_PTR ulUIParam,LPSTR lpszProfileName,LPSTR lpszPassword,FLAGS flFlags,ULONG ulReserved,LPLHANDLE lplhSession);
extern "C" ULONG DLL_EXPORT MAPILogoff(LHANDLE lhSession,ULONG_PTR ulUIParam,FLAGS flFlags,ULONG ulReserved);
extern "C" ULONG DLL_EXPORT MAPISendDocuments(ULONG_PTR ulUIParam,LPSTR lpszDelimChar,LPSTR lpszFilePaths,LPSTR lpszFileNames,ULONG ulReserved);
extern "C" ULONG DLL_EXPORT MAPISendMail(LHANDLE lhSession,ULONG_PTR ulUIParam,lpMapiMessage lpMessage,FLAGS flFlags,ULONG ulReserved);

#endif

这是 main.cpp 文件:

#include "main.h"

// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
ULONG DLL_EXPORT MAPILogon(ULONG_PTR ulUIParam,LPSTR lpszProfileName,LPSTR lpszPassword,FLAGS flFlags,ULONG ulReserved,LPLHANDLE lplhSession)
{
    MessageBoxA(0, "MAPILogon", "MAPILogon", MB_OK | MB_ICONINFORMATION);
    return SUCCESS_SUCCESS;
}
ULONG DLL_EXPORT MAPILogoff(LHANDLE lhSession,ULONG_PTR ulUIParam,FLAGS flFlags,ULONG ulReserved)
{
    MessageBoxA(0, "MAPILogoff", "MAPILogoff", MB_OK | MB_ICONINFORMATION);
    return SUCCESS_SUCCESS;
}
ULONG DLL_EXPORT MAPISendDocuments(ULONG_PTR ulUIParam,LPSTR lpszDelimChar,LPSTR lpszFilePaths,LPSTR lpszFileNames,ULONG ulReserved)
{
    MessageBoxA(0, "MAPISendDocuments", "MAPISendDocuments", MB_OK | MB_ICONINFORMATION);
    return SUCCESS_SUCCESS;
}
ULONG DLL_EXPORT MAPISendMail(LHANDLE lhSession,ULONG_PTR ulUIParam,lpMapiMessage lpMessage,FLAGS flFlags,ULONG ulReserved)
{
    MessageBoxA(0, "MAPISendMail", "MAPISendMail", MB_OK | MB_ICONINFORMATION);
    return SUCCESS_SUCCESS;
}
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}

提前致谢。

乔治

4

1 回答 1

1

在链接中:创建自定义简单 Mapi DLL,执行时抛出错误

Andy 帮我解决了调用约定不正确的问题。

将 WINAPI 添加到我所有的 Simple MAPI 函数声明和定义中,例如:

extern "C" ULONG DLL_EXPORT WINAPI MAPILogon( // etc

然后问题是我导出的函数是用声明导出的。

要在 code::blocks 中更正此问题,您必须添加:

主菜单:项目 -> 构建选项 -> GNU GCC 编译器 -> 链接器设置 -> 其他链接器选项:-Wl,--kill-at

谢谢!

于 2013-05-26T15:35:04.353 回答