You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1127 lines
29 KiB
1127 lines
29 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
install.c
|
|
|
|
Abstract:
|
|
|
|
This module contains installation functions.
|
|
|
|
Author:
|
|
|
|
Andrew Ritz (andrewr) 9-Dec-1997
|
|
|
|
|
|
Revision History:
|
|
4-Dec-1999 Danl Remove CreatePrinterandGroups
|
|
|
|
--*/
|
|
|
|
#include "faxapi.h"
|
|
#pragma hdrstop
|
|
|
|
extern HINSTANCE g_MyhInstance;
|
|
|
|
//
|
|
// Notice: FaxRegisterServiceProvider and FaxUnregisterServiceProvider are
|
|
// implemented directly in winfax.dll since it must exist
|
|
// even before the fax optional component is installed.
|
|
//
|
|
|
|
|
|
#ifdef UNICODE
|
|
BOOL AddMethodKey(
|
|
HKEY hKey,
|
|
LPCWSTR MethodName,
|
|
LPCWSTR FriendlyName,
|
|
LPCWSTR FunctionName,
|
|
LPCWSTR Guid,
|
|
DWORD Priority
|
|
) ;
|
|
#endif // #ifdef UNICODE
|
|
|
|
|
|
#ifdef UNICODE
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxRegisterRoutingExtensionW(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCWSTR lpcwstrExtensionName,
|
|
IN LPCWSTR lpcwstrFriendlyName,
|
|
IN LPCWSTR lpcwstrImageName,
|
|
IN PFAX_ROUTING_INSTALLATION_CALLBACKW pCallBack,
|
|
IN LPVOID lpvContext
|
|
)
|
|
{
|
|
HKEY hKey = NULL;
|
|
BOOL bRetVal = FALSE;
|
|
DWORD dwRet;
|
|
WCHAR szKeyName[2000];
|
|
|
|
PFAX_GLOBAL_ROUTING_INFO pRoutingInfo;
|
|
DWORD dwMethods;
|
|
DWORD dwLastError = ERROR_SUCCESS;
|
|
|
|
WCHAR wszMethodName[101];
|
|
WCHAR wszMethodFriendlyName[101];
|
|
WCHAR wszMethodFunctionName[101];
|
|
WCHAR wszMethodGuid[101];
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxRegisterRoutingExtensionW"));
|
|
|
|
if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() failed"));
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!lpcwstrExtensionName ||
|
|
!lpcwstrFriendlyName ||
|
|
!lpcwstrImageName ||
|
|
!pCallBack)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
DebugPrintEx(DEBUG_ERR, _T("At least one of the given pointers is NULL."));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Local installation only
|
|
//
|
|
if (!IsLocalFaxConnection(hFaxHandle) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, _T("Not a local fax connection"));
|
|
SetLastError(ERROR_INVALID_FUNCTION);
|
|
return FALSE;
|
|
}
|
|
|
|
if ((_wcsicmp( lpcwstrExtensionName, REGKEY_ROUTING_EXTENSION ) != 0) &&
|
|
TRUE == IsDesktopSKU())
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("We do not support non MS routing extensions on desktop SKUs"));
|
|
SetLastError (FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Get the number of current methods for priority
|
|
//
|
|
if (!FaxEnumGlobalRoutingInfo(hFaxHandle, &pRoutingInfo, &dwMethods) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxEnumGlobalRoutingInfo() failed, ec = %d"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Store number of methods returned by EnumGlobalRoutingInfo()
|
|
//
|
|
DWORD dwRegisteredMethods = dwMethods;
|
|
|
|
//
|
|
// Return Value of the Function
|
|
//
|
|
BOOL bResult = TRUE;
|
|
|
|
//
|
|
// Variables to deal with newly registered Guids, to check their uniqueness
|
|
//
|
|
LPTSTR *plptstrNewGuids = NULL;
|
|
LPTSTR lptstrGuid = NULL;
|
|
LPTSTR *pTmp = NULL;
|
|
|
|
//
|
|
// Variable for different FOR cycles
|
|
//
|
|
DWORD i = 0;
|
|
|
|
if (0 > _snwprintf(szKeyName,
|
|
ARR_SIZE(szKeyName) -1,
|
|
TEXT("%s\\%s\\%s"),
|
|
REGKEY_SOFTWARE,
|
|
REGKEY_ROUTING_EXTENSIONS,
|
|
lpcwstrExtensionName))
|
|
{
|
|
//
|
|
// Extension name exceeds size
|
|
//
|
|
DebugPrintEx(DEBUG_ERR, _T("Extension name \"%s\" exceeds size"), lpcwstrExtensionName);
|
|
dwLastError = ERROR_INVALID_PARAMETER;
|
|
bResult = FALSE;
|
|
goto FreeRoutingInfo;
|
|
}
|
|
szKeyName[ARR_SIZE(szKeyName) -1] = _T('\0');
|
|
|
|
//
|
|
// Try to open registry key with the Extension Name
|
|
//
|
|
hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,
|
|
szKeyName,
|
|
FALSE,
|
|
0);
|
|
if (!hKey)
|
|
{
|
|
//
|
|
// This is new Routing Extension, let's register it
|
|
//
|
|
hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,
|
|
szKeyName,
|
|
TRUE,
|
|
0);
|
|
|
|
if (!hKey)
|
|
{
|
|
dwLastError = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
_T("OpenRegistryKey(%s) failed. ec=%ld"),
|
|
szKeyName,
|
|
dwLastError);
|
|
bResult = FALSE;
|
|
goto FreeRoutingInfo;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Such Routing Extension is already registered
|
|
//
|
|
RegCloseKey(hKey);
|
|
DebugPrintEx(DEBUG_ERR, _T("Routing Extension Name is duplicated : %s"), szKeyName);
|
|
|
|
dwLastError = ERROR_INVALID_PARAMETER;
|
|
bResult = FALSE;
|
|
goto FreeRoutingInfo;
|
|
}
|
|
|
|
//
|
|
// Add values
|
|
//
|
|
if (! (SetRegistryString(hKey, REGVAL_FRIENDLY_NAME, lpcwstrFriendlyName) &&
|
|
SetRegistryStringExpand(hKey, REGVAL_IMAGE_NAME, lpcwstrImageName) ))
|
|
{
|
|
dwLastError = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR, _T("SetRegistryString failed. ec=%ld"), dwLastError);
|
|
goto error_exit;
|
|
}
|
|
|
|
dwRet = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
|
|
}
|
|
|
|
wcscat(szKeyName, L"\\");
|
|
wcscat(szKeyName, REGKEY_ROUTING_METHODS);
|
|
hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,
|
|
szKeyName,
|
|
TRUE,
|
|
0);
|
|
|
|
if (!hKey)
|
|
{
|
|
dwLastError = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR, _T("OpenRegistryKey(%s) failed. ec=%ld"), szKeyName, dwLastError);
|
|
goto error_exit;
|
|
}
|
|
|
|
while (TRUE)
|
|
{
|
|
ZeroMemory( wszMethodName, sizeof(wszMethodName) );
|
|
ZeroMemory( wszMethodFriendlyName, sizeof(wszMethodFriendlyName) );
|
|
ZeroMemory( wszMethodFunctionName, sizeof(wszMethodFunctionName) );
|
|
ZeroMemory( wszMethodGuid, sizeof(wszMethodGuid) );
|
|
|
|
__try
|
|
{
|
|
bRetVal = pCallBack(hFaxHandle,
|
|
lpvContext,
|
|
wszMethodName,
|
|
wszMethodFriendlyName,
|
|
wszMethodFunctionName,
|
|
wszMethodGuid
|
|
);
|
|
|
|
if (!bRetVal)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
dwLastError = GetExceptionCode();
|
|
DebugPrintEx(DEBUG_ERR, _T("pCallBack caused exception. ec=%ld"), dwLastError);
|
|
goto error_exit;
|
|
}
|
|
|
|
//
|
|
// Check that Method Name is existing
|
|
//
|
|
if (wcslen(wszMethodName) < 1)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, _T("Callback returned empty MethodName"));
|
|
dwLastError = ERROR_INVALID_PARAMETER;
|
|
goto error_exit;
|
|
}
|
|
|
|
//
|
|
// Check that new Guid is valid GUID
|
|
//
|
|
if ( ERROR_SUCCESS != (dwRet = IsValidGUID(wszMethodGuid)) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
_T("IsValidGUID failed: %s, ec=%d"),
|
|
wszMethodGuid,
|
|
dwRet);
|
|
dwLastError = dwRet;
|
|
goto error_exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Check that new Guid is unique between all already registered Routing Methods
|
|
//
|
|
for ( i = 0 ; i < dwRegisteredMethods ; i++ )
|
|
{
|
|
if ( _tcsicmp(pRoutingInfo[i].Guid, wszMethodGuid) == 0 )
|
|
{
|
|
//
|
|
// Such Guid already registered
|
|
//
|
|
DebugPrintEx(DEBUG_ERR, _T("Duplicated Guid : %s."), wszMethodGuid);
|
|
dwLastError = ERROR_DS_OBJ_GUID_EXISTS;
|
|
goto error_exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check that new Guid is unique between newly added Routing Methods
|
|
//
|
|
if ( plptstrNewGuids )
|
|
{
|
|
//
|
|
// There is ( dwMethods - dwRegisteredMethods ) new Methods
|
|
//
|
|
for( i = 0 ; i < (dwMethods - dwRegisteredMethods) ; i++ )
|
|
{
|
|
if ( _tcsicmp(plptstrNewGuids[i], wszMethodGuid) == 0 )
|
|
{
|
|
//
|
|
// Such Guid already registered
|
|
//
|
|
DebugPrintEx(DEBUG_ERR, _T("Duplicated Guid : %s."), wszMethodGuid);
|
|
dwLastError = ERROR_DS_OBJ_GUID_EXISTS;
|
|
goto error_exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// We're using the dwMethods as priority for new methods
|
|
//
|
|
dwMethods++;
|
|
if (!AddMethodKey(hKey,
|
|
wszMethodName,
|
|
wszMethodFriendlyName,
|
|
wszMethodFunctionName,
|
|
wszMethodGuid,
|
|
dwMethods))
|
|
{
|
|
dwLastError = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR, _T("AddMethodKey failed. ec=%ld"), dwLastError);
|
|
goto error_exit;
|
|
}
|
|
|
|
//
|
|
// We succeded to add a method. Store its Guid to compare with next Methods
|
|
//
|
|
lptstrGuid = (LPTSTR)MemAlloc( ( _tcslen(wszMethodGuid) + 1 ) * sizeof(TCHAR));
|
|
if (!lptstrGuid)
|
|
{
|
|
dwLastError = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(DEBUG_ERR, _T("MemAlloc failed"));
|
|
goto error_exit;
|
|
}
|
|
|
|
_tcscpy(lptstrGuid, wszMethodGuid);
|
|
|
|
//
|
|
// ReAllocate Memory for extended pNewGuids
|
|
//
|
|
if (plptstrNewGuids)
|
|
{
|
|
pTmp = (LPTSTR *)MemReAlloc(plptstrNewGuids,
|
|
(sizeof(LPTSTR)) * (dwMethods - dwRegisteredMethods));
|
|
}
|
|
else
|
|
{
|
|
pTmp = (LPTSTR *)MemAlloc((sizeof(LPTSTR)) * (dwMethods - dwRegisteredMethods));
|
|
}
|
|
if (!pTmp)
|
|
{
|
|
dwLastError = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(DEBUG_ERR, _T("MemReAlloc failed"));
|
|
goto error_exit;
|
|
}
|
|
|
|
plptstrNewGuids = pTmp;
|
|
|
|
//
|
|
// Put also last added Method's Guid
|
|
//
|
|
plptstrNewGuids[ (dwMethods - dwRegisteredMethods - 1) ] = lptstrGuid;
|
|
}
|
|
|
|
dwRet = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
dwLastError = dwRet;
|
|
DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
|
|
}
|
|
|
|
goto FreeRoutingInfo;
|
|
|
|
error_exit:
|
|
|
|
if (hKey)
|
|
{
|
|
dwRet = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Delete the subkey on failure
|
|
//
|
|
wsprintf(szKeyName, L"%s\\%s", REGKEY_SOFTWARE, REGKEY_ROUTING_EXTENSIONS);
|
|
hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, szKeyName, FALSE, 0);
|
|
if (hKey)
|
|
{
|
|
//
|
|
// Delete the Extension Routing Key and all its Subkeys
|
|
//
|
|
dwRet = DeleteRegistryKey(hKey, lpcwstrExtensionName );
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
_T("DeleteRegistryKey (%s) failed. ec=%ld"),
|
|
lpcwstrExtensionName,
|
|
dwRet);
|
|
}
|
|
dwRet = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
|
|
}
|
|
}
|
|
|
|
bResult = FALSE;
|
|
|
|
FreeRoutingInfo:
|
|
|
|
FaxFreeBuffer(pRoutingInfo);
|
|
|
|
if (plptstrNewGuids)
|
|
{
|
|
for ( i = 0 ; i < ( dwMethods - dwRegisteredMethods ) ; i++ )
|
|
{
|
|
MemFree(plptstrNewGuids[i]);
|
|
}
|
|
|
|
MemFree(plptstrNewGuids);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != dwLastError)
|
|
{
|
|
SetLastError(dwLastError);
|
|
}
|
|
return bResult;
|
|
|
|
} // FaxRegisterRoutingExtensionW
|
|
|
|
|
|
BOOL AddMethodKey(
|
|
HKEY hKey,
|
|
LPCWSTR lpcwstrMethodName,
|
|
LPCWSTR lpcwstrFriendlyName,
|
|
LPCWSTR lpcwstrFunctionName,
|
|
LPCWSTR lpcwstrGuid,
|
|
DWORD dwPriority
|
|
)
|
|
{
|
|
HKEY hKeyNew;
|
|
DWORD dwRet;
|
|
DEBUG_FUNCTION_NAME(TEXT("AddMethodKey"));
|
|
|
|
hKeyNew = OpenRegistryKey(hKey,
|
|
lpcwstrMethodName,
|
|
TRUE,
|
|
0);
|
|
if (!hKeyNew)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("OpenRegistryKey(%s) failed. ec=%ld"),
|
|
lpcwstrMethodName,
|
|
GetLastError ());
|
|
return FALSE;
|
|
}
|
|
//
|
|
// Add values
|
|
//
|
|
if (!(SetRegistryString(hKeyNew, REGVAL_FRIENDLY_NAME, lpcwstrFriendlyName) &&
|
|
SetRegistryString(hKeyNew, REGVAL_FUNCTION_NAME, lpcwstrFunctionName) &&
|
|
SetRegistryString(hKeyNew, REGVAL_GUID, lpcwstrGuid) &&
|
|
SetRegistryDword (hKeyNew, REGVAL_ROUTING_PRIORITY, dwPriority)
|
|
))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("SetRegistry failed. ec=%ld"),
|
|
GetLastError ());
|
|
goto error_exit;
|
|
}
|
|
|
|
dwRet = RegCloseKey (hKeyNew);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("RegCloseKey failed. ec=%ld"),
|
|
dwRet);
|
|
}
|
|
return TRUE;
|
|
|
|
error_exit:
|
|
dwRet = RegCloseKey (hKeyNew);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("RegCloseKey failed. ec=%ld"),
|
|
dwRet);
|
|
}
|
|
dwRet = RegDeleteKey (hKey, lpcwstrMethodName);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("RegDeleteKey (%s) failed. ec=%ld"),
|
|
lpcwstrMethodName,
|
|
dwRet);
|
|
}
|
|
return FALSE;
|
|
} // AddMethodKey
|
|
|
|
#else
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxRegisterRoutingExtensionW(
|
|
IN HANDLE FaxHandle,
|
|
IN LPCWSTR ExtensionName,
|
|
IN LPCWSTR FriendlyName,
|
|
IN LPCWSTR ImageName,
|
|
IN PFAX_ROUTING_INSTALLATION_CALLBACKW CallBack,
|
|
IN LPVOID Context
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER (FaxHandle);
|
|
UNREFERENCED_PARAMETER (ExtensionName);
|
|
UNREFERENCED_PARAMETER (FriendlyName);
|
|
UNREFERENCED_PARAMETER (ImageName);
|
|
UNREFERENCED_PARAMETER (CallBack);
|
|
UNREFERENCED_PARAMETER (Context);
|
|
SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#endif // #ifdef UNICODE
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxUnregisterRoutingExtensionA(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCSTR lpctstrExtensionName
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxUnregisterRoutingExtensionA
|
|
|
|
Routine description:
|
|
|
|
Unregisters a routing extension - ANSI version
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Handle to fax server
|
|
lpctstrExtensionName [in] - Extension unique name
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes;
|
|
BOOL bRes;
|
|
LPCWSTR lpcwstrExtensionName = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterRoutingExtensionA"));
|
|
|
|
if (lpctstrExtensionName)
|
|
{
|
|
if (NULL ==
|
|
(lpcwstrExtensionName = AnsiStringToUnicodeString(lpctstrExtensionName))
|
|
)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to convert Extension unique name to UNICODE (ec = %ld)"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
}
|
|
bRes = FaxUnregisterRoutingExtensionW (hFaxHandle, lpcwstrExtensionName);
|
|
MemFree((PVOID)lpcwstrExtensionName);
|
|
return bRes;
|
|
} // FaxUnregisterRoutingExtensionA
|
|
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxUnregisterRoutingExtensionW(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCWSTR lpctstrExtensionName
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxUnregisterRoutingExtensionW
|
|
|
|
Routine description:
|
|
|
|
Unregisters a routing extension - UNICODE version
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Handle to fax server
|
|
lpctstrExtensionName [in] - Extension unique name
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
error_status_t ec;
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterRoutingExtensionW"));
|
|
|
|
if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
|
|
{
|
|
SetLastError (ERROR_INVALID_HANDLE);
|
|
DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() failed."));
|
|
return FALSE;
|
|
}
|
|
if (!lpctstrExtensionName)
|
|
{
|
|
SetLastError (ERROR_INVALID_PARAMETER);
|
|
DebugPrintEx(DEBUG_ERR, _T("lpctstrExtensionName is NULL."));
|
|
return FALSE;
|
|
}
|
|
|
|
__try
|
|
{
|
|
ec = FAX_UnregisterRoutingExtension(
|
|
FH_FAX_HANDLE(hFaxHandle),
|
|
lpctstrExtensionName);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
//
|
|
// For some reason we got an exception.
|
|
//
|
|
ec = GetExceptionCode();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Exception on RPC call to FAX_UnregisterRoutingExtension. (ec: %ld)"),
|
|
ec);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != ec)
|
|
{
|
|
DumpRPCExtendedStatus ();
|
|
SetLastError (ec);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
} // FaxUnregisterRoutingExtensionW
|
|
|
|
|
|
#ifndef UNICODE
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxUnregisterRoutingExtensionX(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCWSTR lpctstrExtensionName
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
UNREFERENCED_PARAMETER (lpctstrExtensionName);
|
|
SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
} // FaxUnregisterRoutingExtensionX
|
|
|
|
#endif // #ifndef UNICODE
|
|
|
|
|
|
//********************************************
|
|
//* FSP registration
|
|
//********************************************
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxRegisterServiceProviderExA(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCSTR lpctstrGUID,
|
|
IN LPCSTR lpctstrFriendlyName,
|
|
IN LPCSTR lpctstrImageName,
|
|
IN LPCSTR lpctstrTspName,
|
|
IN DWORD dwFSPIVersion,
|
|
IN DWORD dwCapabilities
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxRegisterServiceProviderExA
|
|
|
|
Routine description:
|
|
|
|
Registers an FSP - ANSI version
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Handle to fax server
|
|
lpctstrGUID [in] - GUID of FSP
|
|
lpctstrFriendlyName [in] - Friendly name of FSP
|
|
lpctstrImageName [in] - Image name of FSP. May contain environment variables
|
|
lpctstrTspName [in] - TSP name of FSP.
|
|
dwFSPIVersion [in] - FSP's API version.
|
|
dwCapabilities [in] - FSP's extended capabilities.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
LPCWSTR lpcwstrGUID = NULL;
|
|
LPCWSTR lpcwstrFriendlyName = NULL;
|
|
LPCWSTR lpcwstrImageName = NULL;
|
|
LPCWSTR lpcwstrTspName = NULL;
|
|
BOOL bRes = FALSE;
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxRegisterServiceProviderExA"));
|
|
|
|
if (lpctstrGUID)
|
|
{
|
|
if (NULL ==
|
|
(lpcwstrGUID = AnsiStringToUnicodeString(lpctstrGUID))
|
|
)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to convert GUID to UNICODE (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
if (lpctstrFriendlyName)
|
|
{
|
|
if (NULL ==
|
|
(lpcwstrFriendlyName = AnsiStringToUnicodeString(lpctstrFriendlyName))
|
|
)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to convert Friendly Name to UNICODE (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
if (lpctstrImageName)
|
|
{
|
|
if (NULL ==
|
|
(lpcwstrImageName = AnsiStringToUnicodeString(lpctstrImageName))
|
|
)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to convert Image Name to UNICODE (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
if (lpctstrTspName)
|
|
{
|
|
if (NULL ==
|
|
(lpcwstrTspName = AnsiStringToUnicodeString(lpctstrTspName))
|
|
)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to convert TSP name to UNICODE (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
bRes = FaxRegisterServiceProviderExW (
|
|
hFaxHandle,
|
|
lpcwstrGUID,
|
|
lpcwstrFriendlyName,
|
|
lpcwstrImageName,
|
|
lpcwstrTspName,
|
|
dwFSPIVersion,
|
|
dwCapabilities);
|
|
|
|
exit:
|
|
MemFree((PVOID)lpcwstrGUID);
|
|
MemFree((PVOID)lpcwstrFriendlyName);
|
|
MemFree((PVOID)lpcwstrImageName);
|
|
MemFree((PVOID)lpcwstrTspName);
|
|
|
|
return bRes;
|
|
} // FaxRegisterServiceProviderExA
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxRegisterServiceProviderExW(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCWSTR lpctstrGUID,
|
|
IN LPCWSTR lpctstrFriendlyName,
|
|
IN LPCWSTR lpctstrImageName,
|
|
IN LPCWSTR lpctstrTspName,
|
|
IN DWORD dwFSPIVersion,
|
|
IN DWORD dwCapabilities
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxRegisterServiceProviderExW
|
|
|
|
Routine description:
|
|
|
|
Registers an FSP - UNICODE version
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Handle to fax server
|
|
lpctstrGUID [in] - GUID of FSP
|
|
lpctstrFriendlyName [in] - Friendly name of FSP
|
|
lpctstrImageName [in] - Image name of FSP. May contain environment variables
|
|
lpctstrTspName [in] - TSP name of FSP.
|
|
dwFSPIVersion [in] - FSP's API version.
|
|
dwCapabilities [in] - FSP's extended capabilities.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
error_status_t ec;
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxRegisterServiceProviderExW"));
|
|
|
|
if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
|
|
{
|
|
SetLastError (ERROR_INVALID_HANDLE);
|
|
DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() failed."));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Verify version field range
|
|
//
|
|
if (FSPI_API_VERSION_1 != dwFSPIVersion ||
|
|
dwCapabilities)
|
|
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("dwFSPIVersion invalid (0x%08x), or not valid capability (0x%08x)"),
|
|
dwFSPIVersion,
|
|
dwCapabilities);
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
ec = IsValidGUID (lpctstrGUID);
|
|
if (ERROR_SUCCESS != ec)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Invalid GUID (ec: %ld)"),
|
|
ec);
|
|
SetLastError (ec);
|
|
return FALSE;
|
|
}
|
|
|
|
__try
|
|
{
|
|
ec = FAX_RegisterServiceProviderEx(
|
|
FH_FAX_HANDLE(hFaxHandle),
|
|
lpctstrGUID,
|
|
lpctstrFriendlyName,
|
|
lpctstrImageName,
|
|
lpctstrTspName ? lpctstrTspName : L"",
|
|
dwFSPIVersion,
|
|
dwCapabilities);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
//
|
|
// For some reason we got an exception.
|
|
//
|
|
ec = GetExceptionCode();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Exception on RPC call to FAX_RegisterServiceProviderEx. (ec: %ld)"),
|
|
ec);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != ec)
|
|
{
|
|
DumpRPCExtendedStatus ();
|
|
SetLastError (ec);
|
|
return FALSE;
|
|
}
|
|
else if (IsLocalFaxConnection(hFaxHandle))
|
|
{
|
|
//
|
|
// Adding a local FSP.
|
|
// If we don't have a fax printer installed, this is the time to install one.
|
|
//
|
|
AddOrVerifyLocalFaxPrinter();
|
|
}
|
|
return TRUE;
|
|
} // FaxRegisterServiceProviderExW
|
|
|
|
#ifndef UNICODE
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxRegisterServiceProviderExX(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCWSTR lpctstrGUID,
|
|
IN LPCWSTR lpctstrFriendlyName,
|
|
IN LPCWSTR lpctstrImageName,
|
|
IN LPCWSTR lpctstrTspName,
|
|
IN DWORD dwFSPIVersion,
|
|
IN DWORD dwCapabilities
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
UNREFERENCED_PARAMETER (lpctstrGUID);
|
|
UNREFERENCED_PARAMETER (lpctstrFriendlyName);
|
|
UNREFERENCED_PARAMETER (lpctstrImageName);
|
|
UNREFERENCED_PARAMETER (lpctstrTspName);
|
|
UNREFERENCED_PARAMETER (dwFSPIVersion);
|
|
UNREFERENCED_PARAMETER (dwCapabilities);
|
|
SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
} // FaxRegisterServiceProviderExX
|
|
|
|
#endif // #ifndef UNICODE
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxUnregisterServiceProviderExA(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCSTR lpctstrGUID
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxUnregisterServiceProviderExA
|
|
|
|
Routine description:
|
|
|
|
Unregisters an FSP - ANSI version
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Handle to fax server
|
|
lpctstrGUID [in] - GUID of FSP
|
|
(or provider name for legacy FSPs registered
|
|
through FaxRegisterServiceProvider)
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes;
|
|
LPCWSTR lpcwstrGUID = NULL;
|
|
BOOL bRes;
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterServiceProviderExA"));
|
|
|
|
if (lpctstrGUID)
|
|
{
|
|
if (NULL ==
|
|
(lpcwstrGUID = AnsiStringToUnicodeString(lpctstrGUID))
|
|
)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to convert GUID to UNICODE (ec = %ld)"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
}
|
|
bRes = FaxUnregisterServiceProviderExW (hFaxHandle, lpcwstrGUID);
|
|
MemFree((PVOID)lpcwstrGUID);
|
|
return bRes;
|
|
} // FaxUnregisterServiceProviderExA
|
|
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxUnregisterServiceProviderExW(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCWSTR lpctstrGUID
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxUnregisterServiceProviderExW
|
|
|
|
Routine description:
|
|
|
|
Unregisters an FSP - UNICODE version
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Handle to fax server
|
|
lpctstrGUID [in] - GUID of FSP
|
|
(or provider name for legacy FSPs registered
|
|
through FaxRegisterServiceProvider)
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
error_status_t ec;
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterServiceProviderExW"));
|
|
|
|
if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
|
|
{
|
|
SetLastError (ERROR_INVALID_HANDLE);
|
|
DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
|
|
return FALSE;
|
|
}
|
|
|
|
if (!lpctstrGUID)
|
|
{
|
|
SetLastError (ERROR_INVALID_PARAMETER);
|
|
DebugPrintEx(DEBUG_ERR, _T("lpctstrGUID is NULL."));
|
|
return FALSE;
|
|
}
|
|
|
|
__try
|
|
{
|
|
ec = FAX_UnregisterServiceProviderEx(
|
|
FH_FAX_HANDLE(hFaxHandle),
|
|
lpctstrGUID);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
//
|
|
// For some reason we got an exception.
|
|
//
|
|
ec = GetExceptionCode();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Exception on RPC call to FAX_UnregisterServiceProviderEx. (ec: %ld)"),
|
|
ec);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != ec)
|
|
{
|
|
DumpRPCExtendedStatus ();
|
|
SetLastError (ec);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
} // FaxUnregisterServiceProviderExW
|
|
|
|
#ifndef UNICODE
|
|
|
|
WINFAXAPI
|
|
BOOL
|
|
WINAPI
|
|
FaxUnregisterServiceProviderExX(
|
|
IN HANDLE hFaxHandle,
|
|
IN LPCWSTR lpctstrGUID
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
UNREFERENCED_PARAMETER (lpctstrGUID);
|
|
SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
} // FaxUnregisterServiceProviderExX
|
|
|
|
#endif // #ifndef UNICODE
|
|
|