我正在为电话系统编写适配器TSP。此系统具有TAPI API,但它与我尝试启用TAPI的应用程序不兼容。为了从正确的线路拨打电话,我需要知道一些关于谁在提出请求的信息(来自HKCU)。由于TSP在Telephony服务的上下文中运行,我无法直接访问。我的计划是使用LINE_CREATEDIALOGINSTANCE的功能来阅读这些信息。
我遇到的问题是,从TUISPI_providerGenericDialog返回以下堆栈跟踪后,Telephony服务立即崩溃:
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
根据this book,如果未实现TSPI_providerFreeDialogInstance,则Telephony服务将崩溃。我已经实现了这个功能,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;
}
答案 0 :(得分:0)
我不知道,但help for the TUISPICREATEDIALOGINSTANCEPARAMS Structure说lpszUIDLLName
应该是......
指向以NULL结尾的字符串的指针 指定完全限定名称 要在应用程序中加载的UI DLL 上下文
...但是L"TapiAdapter.tsp"
看起来不像UI DLL的完全限定名称(“完全限定”意味着它包含路径名)。你有要加载的UI DLL吗? 是加载了吗?它是否显示对话框?它被卸下了吗?您的TSP中是否存在TUISPI_providerGenericDialog
,或者它是否存在于您的UI DLL中(它们应该是两个不同的DLL)?
答案 1 :(得分:0)
我找到了解决方案:根据MSDN,此事件的LINEEVENT调用的第一个参数需要是HPROVIDER,而不是HTAPILINE。由于LINEEVENT的第一个参数是HTAPILINE类型,因此需要投射HPROVIDER。