/*++ Copyright (C) Microsoft Corporation, 1998 - 1999 All rights reserved. Module Name: prndata.cxx Abstract: Type safe printer data class Author: Steve Kiraly (SteveKi) 24-Aug-1998 Revision History: --*/ #include #pragma hdrstop #include "prndata.hxx" TPrinterDataAccess:: TPrinterDataAccess( IN LPCTSTR pszPrinter, IN EResourceType eResourceType, IN EAccessType eAccessType ) { DBGMSG( DBG_TRACE, ("TPrinterDataAccess::TPrinterDataAccess\n") ); InitializeClassVariables(); PRINTER_DEFAULTS Access = {0, 0, PrinterAccessFlags( eResourceType, eAccessType ) }; // // Null string indicate the local server. // pszPrinter = (pszPrinter && *pszPrinter) ? pszPrinter : NULL; if (OpenPrinter( const_cast( pszPrinter ), &m_hPrinter, &Access)) { m_eAccessType = eAccessType; } } TPrinterDataAccess:: TPrinterDataAccess( IN HANDLE hPrinter ) { DBGMSG( DBG_TRACE, ("TPrinterDataAccess::TPrinterDataAccess\n") ); InitializeClassVariables(); m_hPrinter = hPrinter; m_bAcceptedHandle = TRUE; } TPrinterDataAccess:: ~TPrinterDataAccess( VOID ) { DBGMSG( DBG_TRACE, ("TPrinterDataAccess::~TPrinterDataAccess\n") ); if( !m_bAcceptedHandle && m_hPrinter ) { ClosePrinter( m_hPrinter ); } } BOOL TPrinterDataAccess:: Init( VOID ) const { return m_hPrinter != NULL; } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszValue, IN OUT BOOL &bData ) { return GetDataHelper( NULL, pszValue, kDataTypeBool, &bData, sizeof( BOOL ), NULL ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszValue, IN OUT DWORD &dwData ) { return GetDataHelper( NULL, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ), NULL ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszValue, IN OUT TString &strString ) { return GetDataStringHelper( NULL, pszValue, strString ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszValue, IN OUT TString **ppstrString, IN OUT UINT &nItemCount ) { return GetDataMuliSzStringHelper( NULL, pszValue, ppstrString, nItemCount ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszValue, IN OUT PVOID pData, IN UINT nSize ) { return GetDataHelper( NULL, pszValue, kDataTypeStruct, pData, nSize, NULL ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN OUT BOOL &bData ) { return GetDataHelper( pszKey, pszValue, kDataTypeBool, &bData, sizeof( BOOL ), NULL ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN OUT DWORD &dwData ) { return GetDataHelper( pszKey, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ), NULL ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN OUT TString &strString ) { return GetDataStringHelper( pszKey, pszValue, strString ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN OUT PVOID pData, IN UINT nSize ) { return GetDataHelper( pszKey, pszValue, kDataTypeStruct, pData, nSize, NULL ); } HRESULT TPrinterDataAccess:: Get( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN OUT TString **ppstrString, IN OUT UINT &nItemCount ) { return GetDataMuliSzStringHelper( pszKey, pszValue, ppstrString, nItemCount ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszValue, IN BOOL bData ) { return SetDataHelper( NULL, pszValue, kDataTypeBool, &bData, sizeof( BOOL ) ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszValue, IN DWORD dwData ) { return SetDataHelper( NULL, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ) ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszValue, IN TString &strString ) { return SetDataHelper( NULL, pszValue, kDataTypeString, reinterpret_cast( const_cast( static_cast( strString ) ) ), (strString.uLen() + 1) * sizeof( TCHAR ) ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszValue, IN PVOID pData, IN UINT nSize ) { return SetDataHelper( NULL, pszValue, kDataTypeStruct, pData, nSize ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN PVOID pData, IN UINT nSize ) { return SetDataHelper( pszKey, pszValue, kDataTypeStruct, pData, nSize ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN BOOL bData ) { return SetDataHelper( pszKey, pszValue, kDataTypeBool, &bData, sizeof( BOOL ) ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN DWORD dwData ) { return SetDataHelper( pszKey, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ) ); } HRESULT TPrinterDataAccess:: Set( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN TString &strString ) { return SetDataHelper( pszKey, pszValue, kDataTypeString, reinterpret_cast( const_cast( static_cast( strString ) ) ), (strString.uLen() + 1) * sizeof( TCHAR ) ); } HRESULT TPrinterDataAccess:: Delete( IN LPCTSTR pszValue ) { return DeleteDataHelper( NULL, pszValue ); } HRESULT TPrinterDataAccess:: Delete( IN LPCTSTR pszKey, IN LPCTSTR pszValue ) { return DeleteDataHelper( pszKey, pszValue ); } HRESULT TPrinterDataAccess:: GetDataSize( IN LPCTSTR pszValue, IN DWORD dwType, IN DWORD &nSize ) { return GetDataSizeHelper( NULL, pszValue, dwType, &nSize ); } VOID TPrinterDataAccess:: RelaxReturnTypeCheck( IN BOOL bCheckState ) { m_bRelaxReturnedTypeCheck = bCheckState; } // // Private functions. // VOID TPrinterDataAccess:: InitializeClassVariables( VOID ) { m_hPrinter = NULL; m_eAccessType = kAccessUnknown; m_bAcceptedHandle = FALSE; m_bRelaxReturnedTypeCheck = FALSE; } ACCESS_MASK TPrinterDataAccess:: PrinterAccessFlags( IN EResourceType eResourceType, IN EAccessType eAccessType ) const { static const DWORD adwAccessPrinter[] = { PRINTER_ALL_ACCESS, PRINTER_READ, 0, }; static const DWORD adwAccessServer[] = { SERVER_ALL_ACCESS, SERVER_READ, 0, }; DWORD dwAccess = 0; UINT uAccessType = eAccessType > 3 ? 2 : eAccessType; switch( eResourceType ) { case kResourceServer: dwAccess = adwAccessServer[uAccessType]; break; case kResourcePrinter: dwAccess = adwAccessPrinter[uAccessType]; break; case kResourceUnknown: default: break; } return dwAccess; } DWORD TPrinterDataAccess:: ClassTypeToRegType( IN EDataType eDataType ) const { static const DWORD adwRegTypes[] = { REG_DWORD, REG_DWORD, REG_SZ, REG_BINARY, REG_MULTI_SZ, }; UINT uDataType = eDataType; return adwRegTypes[eDataType]; } TPrinterDataAccess::EDataType TPrinterDataAccess:: RegTypeToClassType( IN DWORD dwDataType ) const { static const ClassTypeMap aClassMap[] = { {REG_DWORD, kDataTypeBool}, {REG_DWORD, kDataTypeDword}, {REG_SZ, kDataTypeString}, {REG_BINARY, kDataTypeStruct} }; EDataType eReturnDataType = kDataTypeUnknown; for( UINT i = 0; i < sizeof(aClassMap) / sizeof(ClassTypeMap); i++ ) { if (aClassMap[i].Reg == dwDataType) { eReturnDataType = aClassMap[i].Class; break; } } return eReturnDataType; } HRESULT TPrinterDataAccess:: GetDataSizeHelper( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN DWORD dwType, IN LPDWORD pdwNeeded ) { return GetDataHelper( pszKey, pszValue, RegTypeToClassType( dwType ), NULL, 0, pdwNeeded ); } HRESULT TPrinterDataAccess:: GetDataHelper( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN EDataType eDataType, IN PVOID pData, IN UINT nSize, IN LPDWORD pdwNeeded ) { DWORD dwNeeded = 0; DWORD dwType = ClassTypeToRegType( eDataType ); DWORD dwStatus = ERROR_SUCCESS; SPLASSERT( pszValue ); if (pszKey) { #if _WIN32_WINNT >= 0x0500 dwStatus = GetPrinterDataEx( m_hPrinter, const_cast( pszKey ), const_cast( pszValue ), &dwType, reinterpret_cast( pData ), nSize, &dwNeeded ); #else dwStatus = ERROR_INVALID_PARAMETER; #endif } else { dwStatus = GetPrinterData( m_hPrinter, const_cast( pszValue ), &dwType, reinterpret_cast( pData ), nSize, &dwNeeded ); } if (!m_bRelaxReturnedTypeCheck && dwType != ClassTypeToRegType( eDataType )) { dwStatus = ERROR_INVALID_PARAMETER; } if (pdwNeeded && dwStatus == ERROR_MORE_DATA) { *pdwNeeded = dwNeeded; dwStatus = ERROR_SUCCESS; } return HRESULT_FROM_WIN32( dwStatus ); } HRESULT TPrinterDataAccess:: SetDataHelper( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN EDataType eDataType, IN PVOID pData, IN UINT nSize ) { SPLASSERT( pszValue ); SPLASSERT( pData ); DWORD dwStatus = ERROR_SUCCESS; DWORD dwType = ClassTypeToRegType( eDataType ); if (pszKey) { #if _WIN32_WINNT >= 0x0500 dwStatus = SetPrinterDataEx( m_hPrinter, const_cast( pszKey ), const_cast( pszValue ), dwType, reinterpret_cast( pData ), nSize ); #else dwStatus = ERROR_INVALID_PARAMETER; #endif } else { dwStatus = SetPrinterData( m_hPrinter, const_cast( pszValue ), dwType, reinterpret_cast( pData ), nSize ); } // // SetPrinterData may return an error code that is successful but // not ERROR_SUCCESS. // if( dwStatus == ERROR_SUCCESS_RESTART_REQUIRED ) { return MAKE_HRESULT( 0, FACILITY_WIN32, dwStatus ); } return HRESULT_FROM_WIN32( dwStatus ); } HRESULT TPrinterDataAccess:: DeleteDataHelper( IN LPCTSTR pszKey, IN LPCTSTR pszValue ) { SPLASSERT( pszValue ); DWORD dwStatus = ERROR_SUCCESS; if (pszKey) { #if _WIN32_WINNT >= 0x0500 SPLASSERT( !pszKey ); dwStatus = DeletePrinterDataEx( m_hPrinter, const_cast( pszKey ), const_cast( pszValue ) ); #endif } else { dwStatus = DeletePrinterData( m_hPrinter, const_cast( pszValue ) ); } return HRESULT_FROM_WIN32( dwStatus ); } HRESULT TPrinterDataAccess:: GetDataStringHelper( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN OUT TString &strString ) { SPLASSERT( pszValue ); DWORD nSize = 0; HRESULT hr = GetDataSizeHelper( pszKey, pszValue, REG_SZ, &nSize ); if (SUCCEEDED( hr )) { auto_ptr pData = new TCHAR[nSize+1]; if (pData.get()) { hr = GetDataHelper( pszKey, pszValue, kDataTypeString, pData.get(), nSize, NULL ); if (SUCCEEDED( hr )) { hr = strString.bUpdate( pData.get() ) ? S_OK : E_FAIL; } } else { hr = E_OUTOFMEMORY; } } return hr; } HRESULT TPrinterDataAccess:: GetDataMuliSzStringHelper( IN LPCTSTR pszKey, IN LPCTSTR pszValue, IN OUT TString **ppstrString, IN UINT &nItemCount ) { SPLASSERT( pszValue ); SPLASSERT( ppstrString ); // // Get the size of the multi-sz string. // DWORD nSize = 0; if( ppstrString ) { *ppstrString = NULL; } HRESULT hr = GetDataSizeHelper( pszKey, pszValue, REG_MULTI_SZ, &nSize ); if(SUCCEEDED(hr)) { // // Allocate the multi-sz string buffer. // auto_ptr pszMultiSzString = new TCHAR [nSize+1]; if (pszMultiSzString.get()) { // // Get the actual data now. // hr = GetDataHelper( pszKey, pszValue, kDataTypeStruct, pszMultiSzString.get(), nSize*sizeof(TCHAR), NULL ); if( SUCCEEDED(hr) ) { // // Count the number of strings. // nItemCount = 0; for( LPCTSTR psz = pszMultiSzString.get(); psz && *psz; psz += _tcslen( psz ) + 1 ) { nItemCount++; } // // Not much to do if there are no strings. // if( nItemCount ) { // // Allocate an array of string objects. // *ppstrString = new TString[nItemCount]; if( *ppstrString ) { // // Copy the multi-sz string into the array strings. // UINT i = 0; for( psz = pszMultiSzString.get(); psz && *psz; psz += _tcslen( psz ) + 1, i++ ) { if( !(*ppstrString)[i].bUpdate( psz ) ) { break; } } // // Set the return value. // hr = ( i != nItemCount ) ? E_FAIL : S_OK; } else { hr = E_OUTOFMEMORY; } } } } else { hr = E_OUTOFMEMORY; } } // // Something failed then abandon the whole // operation and relase the string and nuke the count. // if(FAILED(hr)) { delete [] *ppstrString; *ppstrString = NULL; nItemCount = 0; } return hr; }