Leaked source code of windows server 2003
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.
 
 
 
 
 
 

604 lines
12 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
util.cpp
Abstract:
This module contains utility routines for the fax transport provider.
Author:
Wesley Witt (wesw) 13-Aug-1996
Revision History:
20/10/99 -danl-
Fix GetServerName as GetServerNameFromPrinterName.
dd-mm-yy -author-
description
--*/
#include "faxxp.h"
#include "debugex.h"
#pragma hdrstop
//
// globals
//
BOOL oleInitialized;
LPVOID
MapiMemAlloc(
SIZE_T Size
)
/*++
Routine Description:
Memory allocator.
Arguments:
Size - Number of bytes to allocate.
Return Value:
Pointer to the allocated memory or NULL for failure.
--*/
{
LPVOID ptr=NULL;
HRESULT hResult;
// [Win64bug] gpfnAllocateBuffer should accpet size_t as allocating size
hResult = gpfnAllocateBuffer( DWORD(Size), &ptr );
if (S_OK == hResult)
{
ZeroMemory( ptr, Size );
}
return ptr;
}
LPVOID
MapiMemReAlloc(
LPVOID ptr,
SIZE_T Size
)
/*++
Routine Description:
Memory re-allocator.
Arguments:
ptr - pre-allocated buffer
Size - Number of bytes to allocate.
Return Value:
Pointer to the allocated memory or NULL for failure.
--*/
{
LPVOID NewPtr = NULL;
HRESULT hResult;
// [Win64bug] gpfnAllocateBuffer should accpet size_t as allocating size
hResult = gpfnAllocateMore( DWORD(Size), ptr, &NewPtr );
if (S_OK == hResult)
{
ZeroMemory( NewPtr, Size );
}
return NewPtr;
}
VOID
MapiMemFree(
LPVOID ptr
)
/*++
Routine Description:
Memory de-allocator.
Arguments:
ptr - Pointer to the memory block.
Return Value:
None.
--*/
{
if (ptr)
{
gpfnFreeBuffer( ptr );
}
}
PVOID
MyEnumPrinters(
LPTSTR pServerName,
DWORD level,
OUT PDWORD pcPrinters
)
/*++
Routine Description:
Wrapper function for spooler API EnumPrinters
Arguments:
pServerName - Specifies the name of the print server
level - Level of PRINTER_INFO_x structure
pcPrinters - Returns the number of printers enumerated
Return Value:
Pointer to an array of PRINTER_INFO_x structures
NULL if there is an error
--*/
{
DBG_ENTER(TEXT("MyEnumPrinters"));
PBYTE pPrinterInfo = NULL;
DWORD cb;
// first, we give no printer information buffer, so the function fails, but returns
// in cb the number of bytes needed. then we allocate enough memory,
// and call the function again, this time with all of the needed parameters.
if (! EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
pServerName,
level,
NULL,
0,
&cb,
pcPrinters) //the call failed
&& (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) //this is the reason for failing
&& (pPrinterInfo = (PBYTE)MemAlloc(cb)) //we managed to allocate more memory
&& EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
pServerName,
level,
pPrinterInfo,
cb,
&cb,
pcPrinters)) //and now the call succeded
{
return pPrinterInfo;
}
MemFree(pPrinterInfo);
return NULL;
}
HRESULT WINAPI
OpenServiceProfileSection(
LPMAPISUP pSupObj,
LPPROFSECT * ppProfSectObj
)
/*++
Routine Description:
This function opens the profile section of this service, where the
properties of a FAX provider (AB, MS, or XP) are stored.
Arguments:
pSupObj - Pointer to the provider support object
ppProfSectObj - Where we return a pointer to the service profile
section of the provider
Return Value:
An HRESULT.
--*/
{
HRESULT hResult;
DBG_ENTER(TEXT("OpenServiceProfileSection"),hResult);
SPropTagArray sptService = { 1, { PR_SERVICE_UID } };
LPPROFSECT pProvProfSectObj;
ULONG cValues;
LPSPropValue pProp;
//
// Get the PROVIDER profile section
//
hResult = pSupObj->OpenProfileSection(
NULL,
MAPI_MODIFY,
&pProvProfSectObj
);
if (SUCCEEDED(hResult))
{
// Get the UID of the profile section of the service where this provider is installed
hResult = pProvProfSectObj->GetProps (&sptService, FALSE, &cValues, &pProp);
if (SUCCEEDED(hResult))
{
if (S_OK == hResult)
{
// Now, with the obtained UID, open the profile section of the service
hResult = pSupObj->OpenProfileSection ((LPMAPIUID)pProp->Value.bin.lpb,
MAPI_MODIFY,
ppProfSectObj);
}
else
{
hResult = E_FAIL;
}
MemFree( pProp );
}
pProvProfSectObj->Release();
}
return hResult;
}
LPTSTR
RemoveLastNode(
LPTSTR Path
)
/*++
Routine Description:
Removes the last node from a path string.
Arguments:
Path - Path string.
Return Value:
Pointer to the path string.
--*/
{
LPTSTR Pstr = NULL;
if (Path == NULL || Path[0] == 0)
{
return Path;
}
Pstr = _tcsrchr(Path,TEXT('\\'));
if( Pstr && (*_tcsinc(Pstr)) == '\0' )
{
// the last character is a backslash, truncate it...
_tcsset(Pstr,TEXT('\0'));
Pstr = _tcsdec(Path,Pstr);
}
Pstr = _tcsrchr(Path,TEXT('\\'));
if( Pstr )
{
_tcsnset(_tcsinc(Pstr),TEXT('\0'),1);
}
return Path;
}
PDEVMODE
GetPerUserDevmode(
LPTSTR PrinterName
)
{
PDEVMODE DevMode = NULL;
LONG Size;
PRINTER_DEFAULTS PrinterDefaults;
HANDLE hPrinter;
PrinterDefaults.pDatatype = NULL;
PrinterDefaults.pDevMode = NULL;
PrinterDefaults.DesiredAccess = PRINTER_READ;
if (!OpenPrinter( PrinterName, &hPrinter, &PrinterDefaults ))
{
DebugPrint(( TEXT("OpenPrinter() failed, ec=%d"), ::GetLastError() ));
return NULL;
}
Size = DocumentProperties(
NULL,
hPrinter,
PrinterName,
NULL,
NULL,
0
);
if (Size < 0)
{
goto exit;
}
DevMode = (PDEVMODE) MemAlloc( Size );
if (DevMode == NULL)
{
goto exit;
}
Size = DocumentProperties(
NULL,
hPrinter,
PrinterName,
DevMode,
NULL,
DM_OUT_BUFFER
);
if (Size < 0)
{
MemFree( DevMode );
DevMode = NULL;
goto exit;
}
exit:
ClosePrinter( hPrinter );
return DevMode;
}
DWORD
GetDwordProperty(
LPSPropValue pProps,
DWORD PropId
)
{
if (PROP_TYPE(pProps[PropId].ulPropTag) == PT_ERROR)
{
return 0;
}
return pProps[PropId].Value.ul;
}
DWORD
GetBinaryProperty(
LPSPropValue pProps,
DWORD PropId,
OUT LPVOID Buffer,
DWORD SizeOfBuffer
)
{
if (PROP_TYPE(pProps[PropId].ulPropTag) == PT_ERROR)
{
return 0;
}
if (pProps[PropId].Value.bin.cb > SizeOfBuffer)
{
return 0;
}
CopyMemory( Buffer, pProps[PropId].Value.bin.lpb, pProps[PropId].Value.bin.cb );
return pProps[PropId].Value.bin.cb;
}
PVOID
MyGetPrinter(
LPTSTR PrinterName,
DWORD level
)
/*++
Routine Description:
Wrapper function for GetPrinter spooler API
Arguments:
hPrinter - Identifies the printer in question
level - Specifies the level of PRINTER_INFO_x structure requested
Return Value:
Pointer to a PRINTER_INFO_x structure, NULL if there is an error
--*/
{
DBG_ENTER(TEXT("MyGetPrinter"));
HANDLE hPrinter;
PBYTE pPrinterInfo = NULL;
DWORD cbNeeded;
PRINTER_DEFAULTS PrinterDefaults;
PrinterDefaults.pDatatype = NULL;
PrinterDefaults.pDevMode = NULL;
PrinterDefaults.DesiredAccess = PRINTER_READ; //PRINTER_ALL_ACCESS;
if (!OpenPrinter( PrinterName, &hPrinter, &PrinterDefaults ))
{
CALL_FAIL (GENERAL_ERR, TEXT("OpenPrinter"), ::GetLastError());
return NULL;
}
if (!GetPrinter( hPrinter, level, NULL, 0, &cbNeeded ) &&
::GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
(pPrinterInfo = (PBYTE) MemAlloc( cbNeeded )) &&
GetPrinter( hPrinter, level, pPrinterInfo, cbNeeded, &cbNeeded ))
{
ClosePrinter( hPrinter );
return pPrinterInfo;
}
ClosePrinter( hPrinter );
MemFree( pPrinterInfo );
return NULL;
}
BOOL
GetServerNameFromPrinterName(
LPTSTR lptszPrinterName,
LPTSTR *pptszServerName
)
/*++
Routine Description:
retrieve the server name given a printer name
Arguments:
[in] lptszPrinterName - Identifies the printer in question
[out] lptszServerName - Address of pointer to output string buffer.
NULL indicates local server.
The caller is responsible to free the buffer which
pointer is given in this parameter.
Return Value:
BOOL: TRUE - operation succeeded , FALSE: failed
--*/
{
BOOL bRes = FALSE;
DBG_ENTER(TEXT("GetServerNameFromPrinterName"),bRes);
PPRINTER_INFO_2 ppi2 = NULL;
LPTSTR lptstrBuffer = NULL;
if (lptszPrinterName)
{
if (ppi2 = (PPRINTER_INFO_2) MyGetPrinter(lptszPrinterName,2))
{
bRes = GetServerNameFromPrinterInfo(ppi2,&lptstrBuffer);
MemFree(ppi2);
if (bRes)
{
*pptszServerName = lptstrBuffer;
}
}
}
return bRes;
}
LPTSTR
ConvertAStringToTString(LPCSTR lpcstrSource)
{
LPTSTR lptstrDestination;
if (!lpcstrSource)
return NULL;
#ifdef UNICODE
lptstrDestination = AnsiStringToUnicodeString( lpcstrSource );
#else // !UNICODE
lptstrDestination = StringDup( lpcstrSource );
#endif // UNICODE
return lptstrDestination;
}
LPSTR
ConvertTStringToAString(LPCTSTR lpctstrSource)
{
LPSTR lpstrDestination;
if (!lpctstrSource)
return NULL;
#ifdef UNICODE
lpstrDestination = UnicodeStringToAnsiString( lpctstrSource );
#else // !UNICODE
lpstrDestination = StringDup( lpctstrSource );
#endif // UNICODE
return lpstrDestination;
}
void
ErrorMsgBox(
HINSTANCE hInstance,
DWORD dwMsgId
)
/*++
Routine Description:
Display error message box
Arguments:
hInstance - [in] resource instance handle
dwMsgId - [in] string resource ID
Return Value:
none
--*/
{
TCHAR* ptCaption=NULL;
TCHAR tszCaption[MAX_PATH];
TCHAR tszMessage[MAX_PATH];
DBG_ENTER(TEXT("ErrorMsgBox"));
if(!LoadString( hInstance, IDS_FAX_MESSAGE, tszCaption, sizeof(tszCaption) / sizeof(tszCaption[0])))
{
CALL_FAIL(GENERAL_ERR, TEXT("LoadString"), ::GetLastError());
}
else
{
ptCaption = tszCaption;
}
if(!LoadString( hInstance, dwMsgId, tszMessage, sizeof(tszMessage) / sizeof(tszMessage[0])))
{
CALL_FAIL(GENERAL_ERR, TEXT("LoadString"), ::GetLastError());
Assert(FALSE);
return;
}
MessageBeep(MB_ICONEXCLAMATION);
AlignedMessageBox(NULL, tszMessage, ptCaption, MB_OK | MB_ICONERROR);
}