📄 exports.cpp
字号:
#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 + -