misc.c

来自「wince下的源代码集合打包」· C语言 代码 · 共 1,256 行 · 第 1/3 页

C
1,256
字号
/**************************************************************************//** Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. **//**************************************************************************/////	misc.c		Support files for Telephony Service Provider Interface////	@doc	EX_TSPI////	@topic	TSPI |////		Tspi utilities////#include "windows.h"#include "types.h"#include "memory.h"#include "mcx.h"#include "tspi.h"#include "tspip.h"#include "linklist.h"extern const WCHAR szSettings[];extern const WCHAR szDialSuffix[];const WCHAR szDefaultsName[] = TEXT("Drivers\\Unimodem");// Unimodem thread priority#define DEFAULT_THREAD_PRIORITY 150#define REGISTRY_PRIORITY_VALUE TEXT("Priority256")DWORD g_dwUnimodemThreadPriority;const DEVMINICFG DefaultDevCfg ={    DEVMINCFG_VERSION,          // Version    0x00,                       // WaitBong    90,                         // CallSetupFail    0,                          // ModemOptions    19200,                      // Baud Rate    0,                          // Options    8,                          // Byte Size    0,                          // Stop Bits    0                           // Parity};extern HANDLE g_hCoreDLL;//// Function to complete an outstanding async operation// (unimodem can only handle one outstanding async operation per linedev)//// NOTE: Must be called holding the OpenCS//voidCompleteAsyncOp(    PTLINEDEV pLineDev    ){    DWORD dwID;    DWORD dwStatus;    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:+CompleteAsyncOp\n")));    dwID = pLineDev->dwPendingID;    dwStatus = pLineDev->dwPendingStatus;    switch (pLineDev->dwPendingType) {    case PENDING_LINEACCEPT:    case PENDING_LINEANSWER:    case PENDING_LINEDEVSPECIFIC:    case PENDING_LINEDIAL:    case PENDING_LINEDROP:    case PENDING_LINEMAKECALL:        LeaveCriticalSection(&pLineDev->OpenCS);        DEBUGMSG(ZONE_ASYNC, (TEXT("UNIMODEM:CompleteAsyncOp completing Op %s(0x%x)\n"),                             GetPendingName(pLineDev->dwPendingType), dwID));        TspiGlobals.fnCompletionCallback(dwID, dwStatus);        EnterCriticalSection(&pLineDev->OpenCS);        break;    }    pLineDev->dwPendingID = INVALID_PENDINGID;    pLineDev->dwPendingType = INVALID_PENDINGOP;    pLineDev->dwPendingStatus = 0;    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:-CompleteAsyncOp\n")));}   // CompleteAsyncOp//// NOTE on async operations:// The function that invokes an async operation (TSPI_lineMakeCall, TSPI_lineAnswer, etc)// first calls ControlThreadCmd which calls SetAsyncOp. Just before returning it calls// SetAsyncID in order to avoid calling the TAPI completion callback before the user// knows the async ID. The UnimodemControlThread will call SetAsyncStatus when the// async operation has completed. If the ID has been set, then SetAsyncStatus will perform// the callback.////// Set the async ID for a pending operation. This signals that the function which// invoked the async operation has completed so any subsequent SetAsyncStatus call// will cause a completion callback to TAPI. If the invoked async operation has// already completed (SetAsyncStatus already called), then we need to kick off a// thread to make the callback for this completed async operation.//// Return LINEERR_OPERATIONFAILED if this async operation has been aborted, else// return async ID.//DWORDSetAsyncID(    PTLINEDEV pLineDev,    DWORD dwID    ){    DWORD dwRet = LINEERR_OPERATIONFAILED;    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:+SetAsyncID\n")));    EnterCriticalSection(&pLineDev->OpenCS);    if (pLineDev->dwPendingID != INVALID_PENDINGID) {        LeaveCriticalSection(&pLineDev->OpenCS);    } else {        pLineDev->dwPendingID = dwID;        dwRet = dwID;        //        // If the operation has completed then we need to do the callback on another thread        //        if (pLineDev->dwPendingStatus != LINEERR_ALLOCATED) {            LeaveCriticalSection(&pLineDev->OpenCS);            if (!StartCompleteAsyncOp(pLineDev)) {                dwRet = LINEERR_OPERATIONFAILED;            }        } else {            LeaveCriticalSection(&pLineDev->OpenCS);        }    }    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:-SetAsyncID 0x%x\n"), dwRet));    return dwRet;}   // SetAsyncID//// Set the status for a pending async operation and complete it if possible.//voidSetAsyncStatus(    PTLINEDEV pLineDev,    DWORD dwNewStatus    ){    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:+SetAsyncStatus\n")));    EnterCriticalSection(&pLineDev->OpenCS);    //    // Is there a pending operation to complete?    //    if (pLineDev->dwPendingType != INVALID_PENDINGOP) {        pLineDev->dwPendingStatus = dwNewStatus;        if (pLineDev->dwPendingID != INVALID_PENDINGID) {            CompleteAsyncOp(pLineDev);        }    }    LeaveCriticalSection(&pLineDev->OpenCS);    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:-SetAsyncStatus\n")));}   // SetAsyncStatus//// Abort any previously pending operation and record new pending operation// (called by async TSPI_line* functions)//voidSetAsyncOp(    PTLINEDEV pLineDev,    DWORD dwNewOp    ){    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:+SetAsyncOp\n")));    EnterCriticalSection(&pLineDev->OpenCS);    //    // Is there a pending operation that we need to abort?    //    if (pLineDev->dwPendingType != INVALID_PENDINGOP) {        LeaveCriticalSection(&pLineDev->OpenCS);        SetAsyncStatus(pLineDev, LINEERR_OPERATIONFAILED);        EnterCriticalSection(&pLineDev->OpenCS);    }    pLineDev->dwPendingType = dwNewOp;    pLineDev->dwPendingStatus = LINEERR_ALLOCATED;    pLineDev->dwPendingID = INVALID_PENDINGID;    LeaveCriticalSection(&pLineDev->OpenCS);    DEBUGMSG(ZONE_FUNC|ZONE_ASYNC, (TEXT("UNIMODEM:-SetAsyncOp\n")));}   // SetAsyncOptypedef struct _ASYNCCMD {    DWORD dwRequestID;    DWORD dwResult;} ASYNCCMD, * PASYNCCMD;DWORDAsyncCompleteThread(    PVOID lpvIn    ){    PASYNCCMD pCmd = (PASYNCCMD)lpvIn;    DEBUGMSG(ZONE_ASYNC, (TEXT("UNIMODEM:AsyncCompleteThread completing ID(0x%x) result 0x%x\n"),                         pCmd->dwRequestID, pCmd->dwResult));    TspiGlobals.fnCompletionCallback(pCmd->dwRequestID, pCmd->dwResult);    TSPIFree(pCmd);    return 0;}   // AsyncCompleteThreadBOOLStartCompleteAsyncOp(    PTLINEDEV pLineDev    ){    HANDLE hThd;    PASYNCCMD pCmd;    if (NULL == (pCmd = TSPIAlloc(sizeof(ASYNCCMD)))) {        DEBUGMSG(1, (TEXT("UNIMODEM:StartCompleteAsyncOp Unable to allocate ASYNCCMD!!!\n")));        return FALSE;    }    EnterCriticalSection(&pLineDev->OpenCS);    pCmd->dwRequestID = pLineDev->dwPendingID;    pCmd->dwResult = pLineDev->dwPendingStatus;    pLineDev->dwPendingID = INVALID_PENDINGID;    pLineDev->dwPendingType = INVALID_PENDINGOP;    pLineDev->dwPendingStatus = 0;    LeaveCriticalSection(&pLineDev->OpenCS);    hThd = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)AsyncCompleteThread,                         pCmd, 0, NULL );    if (!hThd) {        DEBUGMSG(1, (TEXT("UNIMODEM:StartCompleteAsyncOp Unable to Create AsyncCompleteThread!!!\n")));        TSPIFree(pCmd);        return FALSE;    }    CloseHandle(hThd);    return TRUE;}   // StartCompleteAsyncOp//// Read the default devconfig for this device from the registry//VOIDgetDefaultDevConfig(    PTLINEDEV ptLineDev,    PDEVMINICFG pDevMiniCfg    ){    static const WCHAR szDevConfig[]    = TEXT("DevConfig");    DWORD dwSize, dwRetCode;        DEBUGMSG(ZONE_FUNC | ZONE_INIT,             (TEXT("UNIMODEM:+getDefaultDevConfig\r\n")));    // Get the default device config from the registry    dwSize = sizeof( DEVMINICFG );    dwRetCode = MdmRegGetValue(ptLineDev, NULL, szDevConfig, REG_BINARY,                               (LPBYTE)pDevMiniCfg, &dwSize);    if( (dwRetCode != ERROR_SUCCESS) ||        (pDevMiniCfg->wVersion != DEVMINCFG_VERSION) ||        (dwSize < (sizeof(DEVMINICFG) - (DIAL_MODIFIER_LEN*sizeof(WCHAR)) )))     {        DEBUGMSG(ZONE_INIT | ZONE_ERROR,                 (TEXT("UNIMODEM:Device Config error, retcode x%X, version x%X (x%X), Size x%X (x%X)\r\n"),                  dwRetCode,                  pDevMiniCfg->wVersion, DEVMINCFG_VERSION,                  dwSize, (sizeof(DEVMINICFG) - (DIAL_MODIFIER_LEN*sizeof(WCHAR)) )) );        // Either the registry value is missing, or it is invalid.        // We need some default, use the one in ROM        *pDevMiniCfg = DefaultDevCfg;    }    pDevMiniCfg->szDialModifier[DIAL_MODIFIER_LEN] = 0; // make sure it is null terminated    DEBUGMSG(ZONE_INIT,             (TEXT("UNIMODEM:Done reading Device Config, retcode x%X\r\n"),              dwRetCode));    DEBUGMSG(ZONE_INIT,             (TEXT("UNIMODEM:Version x%X\tWait Bong x%X\tCall Setup Fail x%X\r\n"),              ptLineDev->DevMiniCfg.wVersion,              ptLineDev->DevMiniCfg.wWaitBong,              ptLineDev->DevMiniCfg.dwCallSetupFailTimer));    DEBUGMSG(ZONE_INIT,             (TEXT("UNIMODEM:Baud %d\tByte Size %d\tStop Bits %d\tParity %d\r\n"),              ptLineDev->DevMiniCfg.dwBaudRate,              ptLineDev->DevMiniCfg.ByteSize,              ptLineDev->DevMiniCfg.StopBits,              ptLineDev->DevMiniCfg.Parity));    DEBUGMSG(ZONE_FUNC | ZONE_INIT,             (TEXT("UNIMODEM:-getDefaultDevConfig\r\n")));}//// Create a LineDev//PTLINEDEVcreateLineDev(    HKEY    hActiveKey,    LPCWSTR lpszDevPath,    LPCWSTR lpszDeviceName    ){    PTLINEDEV ptLineDev;    PTLINEDEV ptExistingDev;    static const WCHAR szDeviceType[]   = TEXT("DeviceType");    static const WCHAR szPortName[]     = TEXT("Port");    static const WCHAR szFriendlyName[] = TEXT("FriendlyName");    static const WCHAR szPnpIdName[]    = TEXT("PnpId");    static const WCHAR szMaxCmd[]       = TEXT("MaxCmd");    static const WCHAR szDialBilling[]  = TEXT("DialBilling");    DWORD dwSize, dwRetCode, dwTemp;    WCHAR szContinuation[16];            DEBUGMSG(ZONE_FUNC|ZONE_INIT,             (TEXT("UNIMODEM:+createLineDev\r\n")));    // We are being asked to create a new linedev - do it    if (!(ptLineDev = (PTLINEDEV) TSPIAlloc(sizeof(TLINEDEV)) )) {        return NULL;    }     // Initialize all of the fields    ptLineDev->dwPendingID = INVALID_PENDINGID;    ptLineDev->dwDefaultMediaModes = LINEMEDIAMODE_DATAMODEM;  // Do this early, NullifyLine uses it    ptLineDev->bControlThreadRunning = FALSE;    NullifyLineDevice( ptLineDev, TRUE );  // also calls getDefaultDevConfig    // Get the device registry handle for later use.    dwRetCode = RegOpenKeyEx(        HKEY_LOCAL_MACHINE,        lpszDevPath,        0,        KEY_READ,        &ptLineDev->hSettingsKey);    if (ERROR_SUCCESS != dwRetCode) {        // We can't very well continue if the registry values aren't there.        DEBUGMSG(ZONE_ERROR|ZONE_INIT,                 (TEXT("UNIMODEM:createLineDev - RegOpenKeyEx %s returned %d.\r\n"),                  lpszDevPath, dwRetCode));        goto abort_buffer_allocated;    } else {        DEBUGMSG(ZONE_MISC|ZONE_INIT,                 (TEXT("UNIMODEM:createLineDev - RegOpenKeyEx %s handle x%X.\r\n"),                  lpszDevPath, ptLineDev->hSettingsKey));    }        // Record the port name, or read it ourselves if NULL    if( NULL == lpszDeviceName ) {        // Get the port name from registry        dwSize = MAXDEVICENAME;        dwRetCode = MdmRegGetValue(ptLineDev, NULL, szPortName, REG_SZ,                                   (LPBYTE)ptLineDev->szDeviceName, &dwSize);        if( dwRetCode != ERROR_SUCCESS ) {            // We can't do much without a port, abort now.            goto abort_registry_opened;        }    } else {        wcscpy( ptLineDev->szDeviceName, lpszDeviceName );    }        // Get the device type from registry    dwSize = sizeof( DWORD );    dwRetCode = MdmRegGetValue(ptLineDev, NULL, szDeviceType, REG_DWORD,                               (LPBYTE)&dwTemp, &dwSize);    if( dwRetCode == ERROR_SUCCESS ) {        DEBUGMSG(ZONE_MISC|ZONE_INIT,                 (TEXT("UNIMODEM:createLineDev - Device type x%X.\r\n"), dwTemp));                ptLineDev->wDeviceType = (WORD)dwTemp;    } else {            DEBUGMSG(ZONE_MISC|ZONE_INIT,                 (TEXT("UNIMODEM:createLineDev - Device type defaulting to NULL_MODEM.\r\n")));                ptLineDev->wDeviceType = DT_NULL_MODEM;  // default type is null    }        // Get the maximum command length from registry    dwSize = sizeof( DWORD );    dwRetCode = MdmRegGetValue(ptLineDev, szSettings, szMaxCmd, REG_DWORD,                               (LPBYTE)&dwTemp, &dwSize);    if( dwRetCode == ERROR_SUCCESS ) {        DEBUGMSG(ZONE_MISC|ZONE_INIT,                 (TEXT("UNIMODEM:createLineDev - Max command length x%X.\r\n"), dwTemp));                ptLineDev->dwMaxCmd = (WORD)dwTemp;    } else {            DEBUGMSG(ZONE_MISC|ZONE_INIT,                 (TEXT("UNIMODEM:createLineDev - Max command length defaulting to x%X.\r\n"), MAX_CMD_LENGTH));                ptLineDev->dwMaxCmd = MAX_CMD_LENGTH;    }    // Get modem command continuation character - assume it is the first character of the dial suffix    dwSize = sizeof( szContinuation );    if (ERROR_SUCCESS != MdmRegGetValue(ptLineDev, szSettings, szDialSuffix,                                    REG_SZ, (PUCHAR)szContinuation, &dwSize) ) {        ptLineDev->chContinuation = ';';    } else {        ptLineDev->chContinuation = szContinuation[0];    }        //    // Get modem dial capabilities    //    ptLineDev->dwDevCapFlags =  LINEDEVCAPFLAGS_DIALQUIET |                                LINEDEVCAPFLAGS_DIALDIALTONE |

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?