1

我试图建立一个茶匙。现在的问题是,我需要(从用户配置所在的 HKCU)获取一些关于谁发出请求的信息。

由于 TSP 在 Telephony 服务的上下文中运行,因此我无法直接访问它。我的计划是使用 的功能LINE_CREATEDIALOGINSTANCE来读取这些信息,就像这里这里描述的一样。

问题再次相似但不相关,电话服务+拨号程序因以下堆栈跟踪而崩溃。

(1e4.e10): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
TSP_ATSPMod!TSPI_lineMakeCall+0x367:
000007fe`f25a53e7 48894828        **mov     qword ptr [rax+28h],rcx** ds:00000000`0000002d=????????????????
0:015> kP
Child-SP          RetAddr           Call Site
00000000`01dbebe0 000007fe`f49c65ca TSP_ATSPMod!TSPI_lineMakeCall(
            unsigned long dwRequestID = 0x103aa, 
            **struct HDRVLINE__ * hdLine = 0x00000000`00000005**, 
            struct HTAPICALL__ * htCall = 0x00000000`00010399, 
            struct HDRVCALL__ ** lphdCall = 0x00000000`00e85ee8, 
            wchar_t * lpszDestAddress = 0x00000000`00e85c80 "T444", 
            unsigned long dwCountryCode = 0, 
            struct linecallparams_tag * lpCallParams = 0x00000000`00e85df0)+0x367 [c:\freedomvoice_tsp\tsp_atspmod\tsp_atspmod.cpp @ 1714]
00000000`01dbec70 000007fe`f49db14c tapisrv+0x165ca
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\RPCRT4.dll - 
00000000`01dbed50 000007fe`fdd523d5 tapisrv!ServiceMain+0x4bb4
00000000`01dbed90 000007fe`fddfb68e RPCRT4!RpcBindingSetAuthInfoW+0xe5
00000000`01dbedf0 000007fe`fdd3ac40 RPCRT4!Ndr64AsyncServerCallAll+0x120e
00000000`01dbf3b0 000007fe`fdd450f4 RPCRT4!NdrServerCallAll+0x40
00000000`01dbf400 000007fe`fdd44f56 RPCRT4!NdrServerCall2+0x1d84
00000000`01dbf430 000007fe`fdd45679 RPCRT4!NdrServerCall2+0x1be6
00000000`01dbf550 000007fe`fdd4532d RPCRT4!NdrServerCall2+0x2309
00000000`01dbf630 000007fe`fdd62e7f RPCRT4!NdrServerCall2+0x1fbd
00000000`01dbf760 000007fe`fdd62a35 RPCRT4!RpcBindingCopy+0x5df
00000000`01dbf8a0 00000000`7739b68b RPCRT4!RpcBindingCopy+0x195
00000000`01dbf930 00000000`7739feff ntdll!TpSetTimer+0x39b
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\kernel32.dll - 
00000000`01dbf9c0 00000000`7727652d ntdll!RtlValidateHeap+0x4af
00000000`01dbfcc0 00000000`773ac521 kernel32!BaseThreadInitThunk+0xd
00000000`01dbfcf0 00000000`00000000 ntdll!RtlUserThreadStart+0x21

而且,崩溃时的寄存器,

0:015> r
rax=**0000000000000005** rbx=0000000000e85c90 rcx=0000000000010399
rdx=000007fef261f988 rsi=0000000000e85c40 rdi=0000000001dbec60
rip=000007fef25a53e7 rsp=0000000001dbebe0 rbp=00000000000103aa
 r8=0000000001dbe6c8  r9=00000000000103aa r10=0000000000000000
r11=0000000000000246 r12=0000000000e85d70 r13=0000000000000002
r14=0000000000e85c7c r15=0000000000e85ec0
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010200

并且,代码片段:

PDRVLINE pLine = (PDRVLINE) hdLine;

*lphdCall = (HDRVCALL)hdLine;

typedef TUISPICREATEDIALOGINSTANCEPARAMS PARAMS;

pLine->htCall = htCall; <========= ********OFFENDING CODE************

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"TSP_ATSPMod.tsp";
lParams->lpParams = lParams + 1;
lParams->dwSize = lLength;

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

看来我们无法hdLine转换为PDRVLINE.

任何想法?

PS:在 VMWare 上使用 Windows 7 x64。

4

2 回答 2

0

最后 MSDN 进行救援:根据 MSDN,该事件的 LINEEVENT 调用的第一个参数需要是 HPROVIDER。但如果你仔细观察,MSDN 说,

hProvider作为TSPI_providerEnumDevices的参数提供给服务提供者的ProviderHandle 。

因此,您必须先保存HPROVIDER hProvider传递给TSPI_providerEnumDevices并在此处使用它。

工作代码是,

PDRVLINE pLine = (PDRVLINE) ghProvider;    
...
(pDI->lpfnEventProc)((HTAPILINE)ghProvider, 0, LINE_CREATEDIALOGINSTANCE, (DWORD)lParams, 0, 0);

还要确保TUISPI_providerGenericDialog正确导出方法。

于 2013-09-07T11:01:30.477 回答
0

你有进步吗?我想我现在明白你想要做什么了。您想发送 LINE_CREATEDIALOGINSTANCE 以响应 TSPI_lineMakeCall 命令,以找出哪个用户正在请求 makecall。那是对的吗?

如果是这样,我认为您当时仍然应该处理一个问题。如果您可以暂时假设用户信息并处理 makecall 请求,您仍然必须首先解决无效的类型转换。为了解决这个问题,请查看 TSPI_lineOpen 代码中的线句柄。在 MakeCall 函数中,您只能取回您在TSPI_lineOpen的第三个参数中为电话服务提供的内容

参数

dwDeviceID标识要打开的线路设备。

htLine 线路设备的 TAPI 句柄,用于后续调用 LINEEVENT 回调过程以识别设备。

lphdLine 一个指向 HDRVLINE 的指针,服务提供者在其中填写线路设备的句柄。

dwTSPIVersion TSPI 版本。 lpfnEventProc指向由 TAPI 提供的 LINEEVENT 回调过程的指针,服务提供者调用它来报告线路上的后续事件。

如果工作正常,请查看您放入 lParams 结构中的字符串指针。这个范围对吗?我会创建一个静态字符串并将变量指向这样的

static WCHAR szUIDLLName[] = L"TSP_ATSPMod.tsp";
lParams->lpszUIDLLName = szUIDLLName;

第三也是最后,我对你如何调用回调函数感到困惑。根据LINE_CREATEDIALOGINSTANCE 文档,您是正确的。但是,如果您查看Line_Event 回调函数,最后三个参数实际上应该是 DWORD_PTR,如果您想编译为 64 位,这很有意义。

这一切真的是评论多于答案。如果有任何意义,请告诉我。这种针对用户和 TSP 的不同上下文过程的解决方案对我来说是新的,我很乐意让它为你工作,因为我可能有一天会想要使用它。

于 2013-09-06T08:56:29.977 回答