2009-10-07 4 views
0

J'écris un adaptateur TSP pour un système téléphonique. Ce système a une API TAPI mais il est incompatible avec l'application que j'essaie d'activer TAPI. Pour passer un appel à partir de la ligne correcte, j'ai besoin de connaître certaines informations (de HKCU) sur qui fait la demande. Puisque le TSP s'exécute dans le contexte du service de téléphonie, je ne peux pas accéder directement. Mon plan était d'utiliser la fonctionnalité de LINE_CREATEDIALOGINSTANCE pour lire cette information.Accéder à HKCU à partir du fournisseur de services TAPI

Le problème que je vais avoir est que le service de téléphonie se bloque immédiatement après le retour de TUISPI_providerGenericDialog avec la trace de pile suivante:

72004400() 
[email protected]() + 0xa93 bytes 
[email protected]() + 0x8f bytes 
[email protected]() + 0x30 bytes 
[email protected]() + 0x217 bytes 
[email protected]() + 0x19 bytes 
[email protected]() + 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 
[email protected]() + 0x34 bytes 

Comme par this book, le service de téléphonie se bloque si TSPI_providerFreeDialogInstance n'est pas mis en œuvre. J'ai implémenté cette fonction et DepWalker la montre comme exportée correctement. ApiSpy32 montre que son adresse est correctement renvoyée via GetProcAddress lorsque mon TSP est chargé. Pourquoi est-ce qu'il continue de s'écraser?

Le code correspondant:

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; 
} 

Répondre

0

J'ai trouvé la solution: Comme par MSDN, le premier paramètre de l'appel LINEEVENT pour cet événement seulement doit être un HPROVIDER, pas HTAPILINE. Puisque le premier paramètre de LINEEVENT est de type HTAPILINE, le HPROVIDER devra être lancé.

0

Je ne sais pas, mais le help for the TUISPICREATEDIALOGINSTANCEPARAMS Structure dit que lpszUIDLLName devrait être ...

pointeur

à une chaîne terminée par NULL spécifiant le complet nom de la DLL interface utilisateur à charger dans l'application contexte

... cependant L"TapiAdapter.tsp" ne ressemble pas à un nom qualifié complet de la DLL de l'interface utilisateur ("entièrement qualifié" signifie qu'il inclut le nom du chemin d'accès). Avez-vous une DLL d'interface utilisateur à charger? Est-ce que est chargé? Est-ce qu'il affiche le dialogue? Est-il déchargé? Est-ce que TUISPI_providerGenericDialog existe dans votre TSP, ou existe-t-il dans votre DLL UI (ils sont supposés être deux DLLs différentes)?

+0

Merci pour les suggestions! En fait, ils ne doivent pas être différents DLL - cette partie du code a été copiée l'exemple ATSP dans le Microsoft TAPI SDK. J'ai essayé le chemin complet. Aucune différence. Le problème n'est pas avec le chargement de la DLL de l'interface utilisateur, mais après le retour de TUISPI_providerGenericDialog. Cela signifie donc également que TUISPI_providerGenericDialog est présent dans mon TSP et qu'il est appelé. –