0

電話システム用のアダプタTSPを書いています。このシステムにはTAPIAPIがありますが、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;
}
4

2 に答える 2

0

わかりませんが、TUISPICREATEDIALOGINSTANCEPARAMS構造のヘルプlpszUIDLLNameは...

アプリケーションコンテキストでロードするUIDLLの完全修飾名を指定するNULLで終了する文字列へのポインタ

...ただしL"TapiAdapter.tsp"、UI DLLの完全修飾名のようには見えません(「完全修飾」とは、パス名が含まれていることを意味します)。ロードするUIDLLはあります?ロードされていますかダイアログが表示されますか?アンロードされていますか?TSPに存在しますかTUISPI_providerGenericDialog、それともUI DLLに存在しますか(2つの異なるDLLであると想定されています)?

于 2009-10-07T23:50:43.980 に答える
0

私は解決策を見つけました:MSDNによると、このイベントのLINEEVENT呼び出しの最初のパラメーターは、HTAPILINEではなくHPROVIDERである必要があります。LINEEVENTの最初のパラメーターはタイプHTAPILINEであるため、HPROVIDERをキャストする必要があります。

于 2009-10-09T14:23:47.593 に答える