从 TAPI 服务提供商访问 HKCU

发布于 2024-08-07 05:00:46 字数 3273 浏览 8 评论 0原文

我正在为电话系统编写适配器 TSP。该系统有一个 TAPI API,但它与我尝试启用 TAPI 的应用程序不兼容。为了从正确的线路拨打电话,我需要(来自 HKCU)了解有关谁提出请求的一些信息。由于 TSP 在电话服务的上下文中运行,因此我无法直接访问。我的计划是使用 LINE_CREATEDIALOGINSTANCE 的功能来读取此信息。

我遇到的问题是电话服务从 TUISPI_providerGenericDialog 返回后立即崩溃,并具有以下堆栈跟踪:

72004400() 
tapisrv.dll!_FreeDialogInstance@20()  + 0xa93 bytes 
tapisrv.dll!_ClientRequest@16()  + 0x8f bytes 
rpcrt4.dll!_Invoke@12()  + 0x30 bytes 
rpcrt4.dll!_NdrStubCall2@16()  + 0x217 bytes 
rpcrt4.dll!_NdrServerCall2@4()  + 0x19 bytes 
rpcrt4.dll!_DispatchToStubInCNoAvrf@12()  + 0x17 bytes 
rpcrt4.dll!RPC_INTERFACE::DispatchToStubWorker()  + 0xae bytes 
rpcrt4.dll!RPC_INTERFACE::DispatchToStub()  + 0x4b bytes 
rpcrt4.dll!LRPC_SCALL::DealWithRequestMessage()  + 0x1d5 bytes 
rpcrt4.dll!LRPC_ADDRESS::DealWithLRPCRequest()  + 0x90 bytes 
rpcrt4.dll!LRPC_ADDRESS::ReceiveLotsaCalls()  + 0x20c bytes 
rpcrt4.dll!RecvLotsaCallsWrapper()  + 0xd bytes 
rpcrt4.dll!BaseCachedThreadRoutine()  + 0x92 bytes 
rpcrt4.dll!ThreadStartRoutine()  + 0x1b bytes 
kernel32.dll!_BaseThreadStart@8()  + 0x34 bytes

根据 本书,如果未实现 TSPI_providerFreeDialogInstance,电话服务将崩溃。我已经实现了这个函数,DepWalker 显示它已正确导出。 ApiSpy32 显示,当加载我的 TSP 时,它的地址已通过 GetProcAddress 正确返回。为什么还是崩溃?

相关代码:

LONG TSPIAPI TSPI_lineMakeCall(DRV_REQUESTID dwRequestID, HDRVLINE hdLine, HTAPICALL htCall,
    LPHDRVCALL lphdCall, LPCWSTR lpszDestAddress, DWORD dwCountryCode, LPLINECALLPARAMS const lpCallParams)
{
    OutputDebugString("TSPI_lineMakeCall\n");
    PDRVLINE pLine = (PDRVLINE) hdLine;

    *lphdCall = (HDRVCALL)hdLine;

    typedef TUISPICREATEDIALOGINSTANCEPARAMS PARAMS;

    pLine->htCall = htCall;
    DWORD lLength = (lstrlenW(lpszDestAddress) + 1) * sizeof(WCHAR);

    PARAMS* lParams = (PARAMS*)DrvAlloc(sizeof(PARAMS) + lLength);
    RtlZeroMemory(lParams, sizeof(PARAMS) + lLength);

    lParams->dwRequestID = dwRequestID;
    lParams->hdDlgInst = (HDRVDIALOGINSTANCE)1000;
    lParams->lpszUIDLLName = L"TapiAdapter.tsp";
    lParams->lpParams = lParams + 1;
    lParams->dwSize = lLength;

    lstrcpyW((LPWSTR)(lParams + 1), lpszDestAddress);
    (*pLine->pfnEventProc)(pLine->htLine, 0, LINE_CREATEDIALOGINSTANCE, (DWORD)lParams, 0, 0);

    return dwRequestID;
}


LONG TSPIAPI TSPI_providerGenericDialogData(DWORD_PTR dwObjectID, DWORD dwObjectType, LPVOID lpParams, DWORD dwSize)
{
    OutputDebugString("TSPI_providerGenericDialogData\n");
    return 0;
}

LONG TSPIAPI TSPI_providerFreeDialogInstance(HDRVDIALOGINSTANCE hdDlgInst)
{
    OutputDebugString("TSPI_providerFreeDialogInstance\n");
    return 0;
}

LONG TSPIAPI TUISPI_providerGenericDialog(TUISPIDLLCALLBACK lpfnUIDLLCallback, HTAPIDIALOGINSTANCE htDlgInst, LPVOID lpParams, DWORD dwSize, HANDLE hEvent)
{
    SetEvent(hEvent);

    LPCWSTR lNumber = (LPCWSTR)lpParams;
    MessageBoxW(0, lNumber, L"Dial Number", MB_OK);

    return 0;
}

I am writing an adapter TSP for a phone system. This system has a TAPI API but it is incompatible with the application I am trying to TAPI-enable. In order to place a call from the correct line, I need to know some information (from HKCU) about who is making the request. Since the TSP runs in the context of the Telephony service, I cannot access is directly. My plan was to use the functionality of LINE_CREATEDIALOGINSTANCE to read this information.

The problem I'm having is that the Telephony service is crashing immediately after returning from TUISPI_providerGenericDialog with the following stack trace:

72004400() 
tapisrv.dll!_FreeDialogInstance@20()  + 0xa93 bytes 
tapisrv.dll!_ClientRequest@16()  + 0x8f bytes 
rpcrt4.dll!_Invoke@12()  + 0x30 bytes 
rpcrt4.dll!_NdrStubCall2@16()  + 0x217 bytes 
rpcrt4.dll!_NdrServerCall2@4()  + 0x19 bytes 
rpcrt4.dll!_DispatchToStubInCNoAvrf@12()  + 0x17 bytes 
rpcrt4.dll!RPC_INTERFACE::DispatchToStubWorker()  + 0xae bytes 
rpcrt4.dll!RPC_INTERFACE::DispatchToStub()  + 0x4b bytes 
rpcrt4.dll!LRPC_SCALL::DealWithRequestMessage()  + 0x1d5 bytes 
rpcrt4.dll!LRPC_ADDRESS::DealWithLRPCRequest()  + 0x90 bytes 
rpcrt4.dll!LRPC_ADDRESS::ReceiveLotsaCalls()  + 0x20c bytes 
rpcrt4.dll!RecvLotsaCallsWrapper()  + 0xd bytes 
rpcrt4.dll!BaseCachedThreadRoutine()  + 0x92 bytes 
rpcrt4.dll!ThreadStartRoutine()  + 0x1b bytes 
kernel32.dll!_BaseThreadStart@8()  + 0x34 bytes

As per this book, the Telephony service will crash if TSPI_providerFreeDialogInstance is not implemented. I have implemented this function and DepWalker shows it as being properly exported. ApiSpy32 shows that its address is correctly returned via GetProcAddress when my TSP is loaded. Why is it still crashing?

The relevant code:

LONG TSPIAPI TSPI_lineMakeCall(DRV_REQUESTID dwRequestID, HDRVLINE hdLine, HTAPICALL htCall,
    LPHDRVCALL lphdCall, LPCWSTR lpszDestAddress, DWORD dwCountryCode, LPLINECALLPARAMS const lpCallParams)
{
    OutputDebugString("TSPI_lineMakeCall\n");
    PDRVLINE pLine = (PDRVLINE) hdLine;

    *lphdCall = (HDRVCALL)hdLine;

    typedef TUISPICREATEDIALOGINSTANCEPARAMS PARAMS;

    pLine->htCall = htCall;
    DWORD lLength = (lstrlenW(lpszDestAddress) + 1) * sizeof(WCHAR);

    PARAMS* lParams = (PARAMS*)DrvAlloc(sizeof(PARAMS) + lLength);
    RtlZeroMemory(lParams, sizeof(PARAMS) + lLength);

    lParams->dwRequestID = dwRequestID;
    lParams->hdDlgInst = (HDRVDIALOGINSTANCE)1000;
    lParams->lpszUIDLLName = L"TapiAdapter.tsp";
    lParams->lpParams = lParams + 1;
    lParams->dwSize = lLength;

    lstrcpyW((LPWSTR)(lParams + 1), lpszDestAddress);
    (*pLine->pfnEventProc)(pLine->htLine, 0, LINE_CREATEDIALOGINSTANCE, (DWORD)lParams, 0, 0);

    return dwRequestID;
}


LONG TSPIAPI TSPI_providerGenericDialogData(DWORD_PTR dwObjectID, DWORD dwObjectType, LPVOID lpParams, DWORD dwSize)
{
    OutputDebugString("TSPI_providerGenericDialogData\n");
    return 0;
}

LONG TSPIAPI TSPI_providerFreeDialogInstance(HDRVDIALOGINSTANCE hdDlgInst)
{
    OutputDebugString("TSPI_providerFreeDialogInstance\n");
    return 0;
}

LONG TSPIAPI TUISPI_providerGenericDialog(TUISPIDLLCALLBACK lpfnUIDLLCallback, HTAPIDIALOGINSTANCE htDlgInst, LPVOID lpParams, DWORD dwSize, HANDLE hEvent)
{
    SetEvent(hEvent);

    LPCWSTR lNumber = (LPCWSTR)lpParams;
    MessageBoxW(0, lNumber, L"Dial Number", MB_OK);

    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

停滞 2024-08-14 05:00:46

我不知道,但是 TUISPICREATEDIALOGINSTANCEPARAMS 结构的帮助< /a> 表示 lpszUIDLLName 应该是 ...

指向以 NULL 结尾的字符串的指针
指定的完全限定名称
要在应用程序中加载的 UI DLL
上下文

...但是 L"TapiAdapter.tsp" 看起来不像 UI DLL 的完全限定名称(“完全限定”意味着它包含路径名)。您要加载的 UI DLL 吗? 加载了吗?是否显示对话框?是否已卸载? TUISPI_providerGenericDialog 是否存在于您的 TSP 中,或者是否存在于您的 UI DLL 中(它们应该是两个不同的 DLL)?

I don't know but the help for the TUISPICREATEDIALOGINSTANCEPARAMS Structure says that lpszUIDLLName should be a ...

pointer to a NULL-terminated string
specifying the fully qualified name of
the UI DLL to load in the application
context

... however L"TapiAdapter.tsp" doesn't look like a fully qualified name of the UI DLL ("fully-qualified" means that it includes the path name). Do you have a UI DLL to be loaded? Is it loaded? Does it display the dialog? Is it unloaded? Does TUISPI_providerGenericDialog exist in your TSP, or does it existin your UI DLL (they're supposed to be two different DLLs)?

泪痕残 2024-08-14 05:00:46

我找到了解决方案:根据 MSDN仅针对此事件的 LINEEVENT 调用的第一个参数需要是 HPROVIDER,而不是 HTAPILINE。由于 LINEEVENT 的第一个参数是 HTAPILINE 类型,因此需要对 HPROVIDER 进行强制转换。

I have found the solution: As per MSDN, the first parameter of the LINEEVENT call for this event only needs to be an HPROVIDER, not an HTAPILINE. Since the first parameter of LINEEVENT is of type HTAPILINE, the HPROVIDER will need to be cast.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文