⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exports.cpp

📁 Dialogic VFX传真卡编程,程序实现了在Windows Fax服务中注册Dialogic VFX传真的功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "stdafx.h"
#include "sivfax.h"
#include "exports.h"
#include "global.h"
#include "resource.h"

BOOL WINAPI FaxDevAbortOperation(IN HANDLE  FaxHandle)
{
	WriteDebugString(L"%s",L"FaxDevAbortOperation Information Enter");

	WriteDebugString(L"%s",L"FaxDevAbortOperation Infromation Leave");

	return TRUE;
}

BOOL WINAPI FaxDevEndJob(IN HANDLE  FaxHandle)
{
	WriteDebugString(L"%s",L"========FaxDevEndJob Enter========");
	//校验所有堆,确认他们的可用性
/*
	DWORD dwHeaps;
	HANDLE	hHeap[50];
	dwHeaps = GetProcessHeaps(50,hHeap);
	WriteDebugString(L"Heap Count:%d",dwHeaps);
	for (DWORD dwCount = 0 ; dwCount < dwHeaps ; dwCount ++)
	{
		if (HeapValidate(hHeap[dwCount],0,NULL) == FALSE)
			WriteDebugString(L"%s",L"Error in some Heap");

	}
	if(!HeapValidate(g_HeapHandle,0,NULL))
		WriteDebugString(L"%s",L"Error in main Heap");
*/
	if (NULL == FaxHandle)
	{
		WriteDebugString(L"%s",L"FaxDevEndJob: Error FaxHandle is NULL");
		SetLastError(ERROR_INVALID_HANDLE);
		return FALSE;
	}

	PJOB_INFO		pJobInfo;
	PDEVICE_INFO	pDeviceInfo;
	pJobInfo = (PJOB_INFO)FaxHandle;
	
	pDeviceInfo = pJobInfo->pDeviceInfo;
	if (pDeviceInfo == NULL)
	{
		WriteDebugString(L"%s",L"FaxDevEndJob: Error pDeviceInfo is NULL");
	}

//	EnterCriticalSection(&pDeviceInfo->cs);

//	LeaveCriticalSection(&pDeviceInfo->cs);
	if(dx_sethook(pDeviceInfo->VoxHandle,DX_ONHOOK,EV_SYNC) == -1)
	{
		WriteDebugString(L"%s",L"FaxDevEndJob: Error Dialogic Function dx_sethook");
	}

	
	EnterCriticalSection(&pDeviceInfo->cs);
    if (pJobInfo->FileName != NULL) 
	{
//		WriteDebugString(L"%s:%s",L"FaxDevEndJob: Information FileName",pJobInfo->FileName);
        MemFreeMacro(pJobInfo->FileName);
    }
    if (pJobInfo->CallerName != NULL) 
	{
//		WriteDebugString(L"%s:%s",L"FaxDevEndJob: Information CallerName",pJobInfo->CallerName);
        MemFreeMacro(pJobInfo->CallerName);
    }
    if (pJobInfo->CallerNumber != NULL) 
	{
//		WriteDebugString(L"%s:%s",L"FaxDevEndJob: Information CallerNumber",pJobInfo->CallerNumber);
        MemFreeMacro(pJobInfo->CallerNumber);
    }
    if (pJobInfo->ReceiverName != NULL) 
	{
//		WriteDebugString(L"%s:%s",L"FaxDevEndJob: Information ReceiverName",pJobInfo->ReceiverName);
        MemFreeMacro(pJobInfo->ReceiverName);
    }
    if (pJobInfo->ReceiverNumber != NULL) 
	{
//		WriteDebugString(L"%s:%s",L"FaxDevEndJob: Information ReceiverNumber",pJobInfo->ReceiverNumber);
        MemFreeMacro(pJobInfo->ReceiverNumber);
    }
    if (pJobInfo->CSI != NULL) 
	{
//		WriteDebugString(L"%s:%s",L"FaxDevEndJob: Information CSI",pJobInfo->CSI);
        MemFreeMacro(pJobInfo->CSI);
    }
    if (pJobInfo->CallerId != NULL) 
	{
//		WriteDebugString(L"%s:%d",L"FaxDevEndJob: Information CallerId",pJobInfo->CallerId);
        MemFreeMacro(pJobInfo->CallerId);
    }
    if (pJobInfo->RoutingInfo != NULL) 
	{
//		WriteDebugString(L"%s:%s",L"FaxDevEndJob: Information RoutingInfo",pJobInfo->RoutingInfo);
        MemFreeMacro(pJobInfo->RoutingInfo);
    }
	
	MemFreeMacro(pJobInfo);
    pDeviceInfo->Status = DEVICE_IDLE;
    // Initialize the virtual fax device's associated fax job
    pDeviceInfo->pJobInfo = NULL;

	if(pDeviceInfo->EnableReceive == 1)
	{
		WriteDebugString(L"%s",L"Enable Receive");
		int nRet = dx_setevtmsk(pDeviceInfo->VoxHandle,DM_RINGS);
		if (nRet == -1)
			WriteDebugString(L"%s",L"FaxDevEndJob: Warnning Dialogic Function Call dx_setevtmsk error");

		nRet = dx_setparm(pDeviceInfo->VoxHandle,DXCH_RINGCNT,(void *)&(pDeviceInfo->Rings));
		if (nRet == -1)
			WriteDebugString(L"%s",L"FaxDevEndJob: Warnning Dialogic Function Call dx_setparm error");
	}
	LeaveCriticalSection(&pDeviceInfo->cs);
	WriteDebugString(L"%s",L"========FaxDevEndJob Leave========");
	return TRUE;
}

//==============================================================================
//函数:FaxDevInitialize
//功能:Initialize the fax service provider
//参数:
//		IN  HLINEAPP LineAppHandle
//		IN  HANDLE HeapHandle
//		OUT PFAX_LINECALLBACK *LineCallbackFunction
//		IN  PFAX_SERVICE_CALLBACK  FaxServiceCallback
//返回值:
//==============================================================================
BOOL WINAPI FaxDevInitialize(
    IN  HLINEAPP               LineAppHandle,
    IN  HANDLE                 HeapHandle,
    OUT PFAX_LINECALLBACK      *LineCallbackFunction,
    IN  PFAX_SERVICE_CALLBACK  FaxServiceCallback
	)
{
	WriteDebugString(L"%s",L"=============FaxDevInitialize Start=================");
	WriteDebugString(L"FaxDevInitialize Param:%8x",LineAppHandle);	
	//保存Tapi Handle 和传真服务分配给本FSP的堆
	g_LineAppHandle = LineAppHandle;
    MemInitializeMacro(HeapHandle);

	//设置线路通知回调函数,在用户更改某条线路状态(接收、发送)时,予以调用
	*LineCallbackFunction = FaxLineCallback;
	
	g_pDeviceInfo = (PDEVICE_INFO*)MemAllocMacro(sizeof(PDEVICE_INFO)*g_dwLines);
	if (NULL == g_pDeviceInfo)
	{
		WriteDebugString(L"%s",L"FaxDevInitialize: Allocate DeviceInfo Struct Error,Outof Memory");
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return FALSE;
	}
	
	//从注册表HKLM\SOFTWARE\Microsoft\Fax\Device Providers\SIVFax\Devices下
	//读取Dialogic卡端口配置信息
	//Linex (REG_SZ) dxxxBnCm
	HKEY hKey = ERROR_SUCCESS;
	LONG lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,DEVICE_LINES_REG,0,KEY_ALL_ACCESS,&hKey);
	if (lRet !=	ERROR_SUCCESS)
	{
		WriteDebugString(L"%s",L"Read Config Info Error,No Devices Key");
		return FALSE;
	}

	char szTemp[13] , szLineName[13];
	DWORD dwSize , dwType;

	for ( DWORD i = 0 ; i < g_dwLines ; i ++ )
	{
		wsprintfA(szTemp,"Line%d",i);
		dwSize = 13;

		//获得对应的虚拟线路的Dialogic卡端口名称
		lRet = RegQueryValueExA(hKey,szTemp,0,&dwType,(LPBYTE)szLineName,&dwSize);
		if ((lRet == ERROR_SUCCESS) && (dwType == REG_SZ))
		{
			g_pDeviceInfo[i] = (PDEVICE_INFO)MemAllocMacro(sizeof(DEVICE_INFO));
			if (NULL == g_pDeviceInfo[i])
			{
				RegCloseKey(hKey);
				for ( int j = i -1 ; j > 0 ; j --)
					MemFreeMacro(g_pDeviceInfo[j]);
				MemFreeMacro(g_pDeviceInfo);
				WriteDebugString(L"%s",L"FaxDevInitialize: Error Outof memory");
				SetLastError(ERROR_NOT_ENOUGH_MEMORY);
				return FALSE;
			}
			//保存Dialogic通道名称
			lstrcpynA( g_pDeviceInfo[i]->ChannelName,szLineName,12);
			
			//初始化关键节
			InitializeCriticalSection(&(g_pDeviceInfo[i]->cs));
		}
		else
		{
			WriteDebugString(L"FaxDevInitialize: Line%d ConfigInfo Error",i);
			RegCloseKey(hKey);
			for ( int j = i -1 ; j > 0 ; j --)
				MemFreeMacro(g_pDeviceInfo[j]);
			MemFreeMacro(g_pDeviceInfo);
			return FALSE;
		}
	}
	RegCloseKey(hKey);

	//从HKLM\SOFTWARE\Microsft\Fax\Devices\<线路ID>下读取
	//振铃设置,以及CSID
	char szRegPath[1024];
	for ( i = 0 ; i < g_dwLines ; i ++ )
	{
		wsprintfA(szRegPath,"SOFTWARE\\Microsoft\\Fax\\Devices\\%08d", DEVICE_ID_PREFIX + i );
		lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,szRegPath,0,KEY_ALL_ACCESS,&hKey);
		if (lRet != ERROR_SUCCESS)
		{
			for ( DWORD j = 0 ; j < g_dwLines ; j ++ )
				MemFreeMacro(g_pDeviceInfo[j]);
			MemFreeMacro(g_pDeviceInfo);
			WriteDebugString(L"%s",L"FaxDevInitialize: Open Line Config Info Error");
			return FALSE;
		}

		PDEVICE_INFO pCurrentDevice;
		pCurrentDevice = g_pDeviceInfo[i];
		DWORD dwType,dwLen;
		
		pCurrentDevice->pJobInfo = NULL;
		pCurrentDevice->Status = DEVICE_IDLE;
		pCurrentDevice->DeviceId = i;		
		//Called Station Identifer
		dwLen = 21;
		lRet = RegQueryValueExA(hKey,"CSID",0,&dwType,(LPBYTE)(pCurrentDevice->LOCALID),&dwLen);
		if (lRet != ERROR_SUCCESS)
		{
			lstrcpyA(pCurrentDevice->LOCALID,"SIVFax");
			WriteDebugString(L"%s",L"FaxDevInitialize: Waring RegQueryValueEx With CLSID Error");
		}

		//Rings Before Answer
		dwLen = sizeof(DWORD);
		lRet = RegQueryValueExA(hKey,"Rings",0,&dwType,(LPBYTE)&(pCurrentDevice->Rings),&dwLen);
		if (lRet != ERROR_SUCCESS)
		{
			pCurrentDevice->Rings = 3;
			WriteDebugString(L"%s",L"FaxDevInitialize: Warnning RegQueryValueEx With Rings");
		}
		RegCloseKey(hKey);

		//打开Voice 和 Fax Handle
		pCurrentDevice->VoxHandle = dx_open(pCurrentDevice->ChannelName,0);
		if (pCurrentDevice->VoxHandle == -1)
		{
			WriteDebugString(L"%s",L"FaxDevInitialize: Error Dialogic Function Call dx_open return -1");
			for ( DWORD j = 0 ; j < g_dwLines ; j ++ )
				MemFreeMacro(g_pDeviceInfo[j]);
			MemFreeMacro(g_pDeviceInfo);
			return FALSE;
		}
		pCurrentDevice->FaxHandle = fx_open(pCurrentDevice->ChannelName,0);
		if (pCurrentDevice->FaxHandle == -1)
		{
			WriteDebugString(L"%s",L"FaxDevInitialize: Error Dialogic Function Call fx_open return -1");
			for (DWORD j = 0 ; j < g_dwLines ; j ++ )
				MemFreeMacro(g_pDeviceInfo[j]);
			MemFreeMacro(g_pDeviceInfo);
			return FALSE;
		}

		//设置句柄用户相关信息
		lRet = sr_setparm(pCurrentDevice->VoxHandle,SR_USERCONTEXT,(void *)&pCurrentDevice);
		if (lRet == -1)
		{
			WriteDebugString(L"%s",L"FaxDevInitialize: Error Dialogic Function Call sr_setparm SR_USERCONTEXT for voxHandle return -1");
			for (DWORD j = 0 ; j < g_dwLines ; j ++ )
				MemFreeMacro(g_pDeviceInfo[j]);
			MemFreeMacro(g_pDeviceInfo);
			return FALSE;
		}
		lRet = sr_setparm(pCurrentDevice->FaxHandle,SR_USERCONTEXT,(void *)&pCurrentDevice);
		if (lRet == -1)
		{
			WriteDebugString(L"%s",L"FaxDevInitialize: Error Dialogic Function Call sr_setparm SR_USERCONTEXT for faxHandle return -1");
			for (DWORD j = 0 ; j < g_dwLines ; j ++ )
				MemFreeMacro(g_pDeviceInfo[j]);
			MemFreeMacro(g_pDeviceInfo);
			return FALSE;
		}
	}

	//启用完成端口事件通知
	g_hCallbackIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,0);
	if (g_hCallbackIocp == NULL)
	{
		for (DWORD j = 0 ; j < g_dwLines ; j ++ )
			MemFreeMacro(g_pDeviceInfo[j]);
		MemFreeMacro(g_pDeviceInfo);
		WriteDebugString(L"%s",L"FaxDevInitialize: Error CreateIoCompletionPort Error");
		return FALSE;
	}

	SRLWIN32INFO	srinfo;
	srinfo.dwTotalSize = sizeof(SRLWIN32INFO);
	srinfo.ObjectHandle = g_hCallbackIocp;
	srinfo.UserKey = DIALOGIC_EVENT;
	srinfo.dwHandleType = SR_IOCOMPLETIONPORT;
	srinfo.lpOverlapped = (LPOVERLAPPED)NULL;
	lRet = sr_setparm(SRL_DEVICE,SR_WIN32INFO,(void *)&srinfo);
	if (lRet == -1)
	{
		WriteDebugString(L"%s",L"FaxDevInitialize: Error Dialogic Function Call sr_setparm SR_WIN32INFO error");
		for (DWORD j = 0 ; j < g_dwLines ; j ++ )
			MemFreeMacro(g_pDeviceInfo[j]);
		MemFreeMacro(g_pDeviceInfo);
		return FALSE;
	}
	
	//创建线程接收振铃消息和PhaseB及PhaseD消息

	DWORD dwThreadId;
	g_hWorkerThread = (HANDLE)_beginthreadex(NULL,0,(unsigned int ( _stdcall *)(void *))WorkerThread,
		(LPVOID)NULL,0,(unsigned int *)&dwThreadId);
	if (g_hWorkerThread == NULL)
	{
		for (DWORD j = 0 ; j < g_dwLines ; j ++ )
			MemFreeMacro(g_pDeviceInfo[j]);
		MemFreeMacro(g_pDeviceInfo);
		WriteDebugString(L"%s",L"FaxDevInitialize: Error CreateThread Error");
		return FALSE;
	}

	//给后台线程运行机会,启动事件侦听服务
	Sleep(100);
	WriteDebugString(L"%s",L"=============FaxDevInitialize End=================");
	return TRUE;
}

BOOL WINAPI FaxDevReceive(
    IN     HANDLE        FaxHandle,
    IN     HCALL         CallHandle,
    IN OUT PFAX_RECEIVE  FaxReceive
	)
{
	WriteDebugString(L"%s",L"=============FaxDevReceive: Information Enter=============");
	PJOB_INFO pJobInfo;
	pJobInfo = (PJOB_INFO)FaxHandle;
	PDEVICE_INFO pd;
	int nRet;

	pd = pJobInfo->pDeviceInfo;
	EnterCriticalSection(&pd->cs);
	pd->Status = DEVICE_RECEIVE;
	pJobInfo->JobType = JOB_RECEIVE;
	pJobInfo->CallHandle = CallHandle;
    if (FaxReceive->FileName != NULL) 
	{
//		WriteDebugString(L"FileName:%s",FaxReceive->FileName);
        pJobInfo->FileName = (LPWSTR)MemAllocMacro((lstrlen(FaxReceive->FileName) + 1) * sizeof(WCHAR));
        if (pJobInfo->FileName != NULL) {
            lstrcpy(pJobInfo->FileName, FaxReceive->FileName);
        }
    }
	if (FaxReceive->ReceiverName != NULL)
	{
//		WriteDebugString(L"ReceiverName:%s",FaxReceive->ReceiverName);
	}
	if(FaxReceive->ReceiverNumber != NULL)
	{
//		WriteDebugString(L"ReceiverNumber:%s",FaxReceive->ReceiverNumber);
	}
	LeaveCriticalSection(&pd->cs);
//	DX_CAP dxcap;
	nRet = dx_setevtmsk(pd->VoxHandle,0);
	if (nRet == -1)
		WriteDebugString(L"%s",L"FaxDevSend: Dialogic Function Call dx_setevtmsk RINGS OFF errro");

	nRet = dx_sethook(pd->VoxHandle,DX_OFFHOOK,EV_SYNC);
	if (nRet == -1)
	{
		WriteDebugString(L"%s",L"FaxDevReceive: Error dx_sethook OFFHOOK error");
		EnterCriticalSection(&pd->cs);
		pJobInfo->Status = FS_LINE_UNAVAILABLE;
		PostJobStatus2(pd,ERROR_SUCCESS);
		LeaveCriticalSection(&pd->cs);
		return FALSE;
	}
	Sleep(1000);
	EnterCriticalSection(&pd->cs);
	pJobInfo->Status = FS_ANSWERED;
	PostJobStatus2(pd,ERROR_SUCCESS);
	LeaveCriticalSection(&pd->cs);

	nRet = fx_initstat(pd->FaxHandle,DF_RX);
	if(nRet == -1)
	{
		WriteDebugString(L"%s",L"FaxDevReceive: Error fx_initstat error");
		EnterCriticalSection(&pd->cs);
		pJobInfo->Status = FS_LINE_UNAVAILABLE;
		PostJobStatus2(pd,ERROR_SUCCESS);
		LeaveCriticalSection(&pd->cs);
		return FALSE;

⌨️ 快捷键说明

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