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.
391 lines
9.8 KiB
391 lines
9.8 KiB
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright 2001 - 2003 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// FILE: Features.cpp
|
|
//
|
|
//
|
|
// PURPOSE: Implementation wrapper class for WinXP PS Driver Features and Options.
|
|
//
|
|
//
|
|
//
|
|
// PLATFORMS: Windows XP, Windows Server 2003
|
|
//
|
|
//
|
|
|
|
#include "precomp.h"
|
|
#include "debug.h"
|
|
#include "oemui.h"
|
|
#include "stringutils.h"
|
|
|
|
// StrSafe.h needs to be included last
|
|
// to disallow bad string functions.
|
|
#include <STRSAFE.H>
|
|
|
|
|
|
|
|
|
|
|
|
// Create a list of pointers to the strings
|
|
// in a multi-sz.
|
|
HRESULT MakeStrPtrList(HANDLE hHeap, PCSTR pmszMultiSz, PCSTR **pppszList, PWORD pwCount)
|
|
{
|
|
PCSTR *ppszList = NULL;
|
|
HRESULT hrResult = S_OK;
|
|
|
|
|
|
// Validate parameters
|
|
if( (NULL == hHeap)
|
|
||
|
|
(NULL == pmszMultiSz)
|
|
||
|
|
(NULL == pppszList)
|
|
||
|
|
(NULL == pwCount)
|
|
)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// Get the count of strings in the multi-sz.
|
|
*pwCount = mstrcount(pmszMultiSz);
|
|
if(0 == *pwCount)
|
|
{
|
|
WARNING(DLLTEXT("MakeStrPtrList() pmszMultiSz contains no strings.\r\n"));
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
// Allocate pointer list.
|
|
*pppszList = (PCSTR *) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (*pwCount) * sizeof(PCSTR));
|
|
if(NULL == *pppszList)
|
|
{
|
|
ERR(ERRORTEXT("MakeStrPtrList() failed to allote array of PCSTR.\r\n"));
|
|
|
|
hrResult = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
ppszList = *pppszList;
|
|
|
|
// Walk multi-sz mapping string pointers.
|
|
for(WORD wIndex = 0; wIndex < *pwCount; ++wIndex)
|
|
{
|
|
ppszList[wIndex] = pmszMultiSz;
|
|
pmszMultiSz += lstrlenA(pmszMultiSz) + 1;
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
return hrResult;
|
|
}
|
|
|
|
|
|
// Determine how many strings are in the multi-sz.
|
|
WORD mstrcount(PCSTR pmszMultiSz)
|
|
{
|
|
WORD wCount = 0;
|
|
|
|
|
|
// NULL string pointers have no strings.
|
|
if(NULL == pmszMultiSz)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Walk list of strings counting them.
|
|
while(pmszMultiSz[0] != '\0')
|
|
{
|
|
++wCount;
|
|
pmszMultiSz += lstrlenA(pmszMultiSz) + 1;
|
|
}
|
|
|
|
return wCount;
|
|
}
|
|
|
|
// Allocates and converts ANSI string to Unicode.
|
|
PWSTR MakeUnicodeString(HANDLE hHeap, PCSTR pszAnsi)
|
|
{
|
|
int nSize = 0;
|
|
PWSTR pszUnicode = NULL;
|
|
|
|
|
|
// Validate parameters
|
|
if( (NULL == hHeap)
|
|
||
|
|
(NULL == pszAnsi)
|
|
)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Get the size needed for UNICODE string.
|
|
nSize = MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, NULL, 0);
|
|
if(0 != nSize)
|
|
{
|
|
// Allocate unicode string.
|
|
pszUnicode = (PWSTR) HeapAlloc(hHeap, 0, nSize * sizeof(WCHAR));
|
|
if(NULL != pszUnicode)
|
|
{
|
|
// Convert ANSI to Unicode
|
|
nSize = MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, pszUnicode, nSize);
|
|
if(0 == nSize)
|
|
{
|
|
// INVARIANT: failed to convert.
|
|
|
|
// free buffer and return NULL.
|
|
HeapFree(hHeap, 0, pszUnicode);
|
|
pszUnicode = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pszUnicode;
|
|
}
|
|
|
|
// Allocates and copies source string.
|
|
PWSTR MakeStringCopy(HANDLE hHeap, PCWSTR pszSource)
|
|
{
|
|
PWSTR pszCopy = NULL;
|
|
DWORD dwSize;
|
|
|
|
|
|
// Validate parameters
|
|
if( (NULL == hHeap)
|
|
||
|
|
(NULL == pszSource)
|
|
)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Allocate memory for string duplication, and duplicate the string.
|
|
dwSize = (wcslen(pszSource) + 1) * sizeof(WCHAR);
|
|
pszCopy = (PWSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize);
|
|
if(NULL != pszCopy)
|
|
{
|
|
HRESULT hResult;
|
|
|
|
|
|
hResult = StringCbCopyW(pszCopy, dwSize, pszSource);
|
|
if(FAILED(hResult))
|
|
{
|
|
HeapFree(hHeap, 0, pszCopy);
|
|
pszCopy = NULL;
|
|
SetLastError(hResult);
|
|
}
|
|
}
|
|
|
|
return pszCopy;
|
|
}
|
|
|
|
// Allocates and copies source string.
|
|
PSTR MakeStringCopy(HANDLE hHeap, PCSTR pszSource)
|
|
{
|
|
PSTR pszCopy = NULL;
|
|
DWORD dwSize;
|
|
|
|
|
|
// Validate parameters
|
|
if( (NULL == hHeap)
|
|
||
|
|
(NULL == pszSource)
|
|
)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Allocate memory for string duplication, and duplicate the string.
|
|
dwSize = (lstrlenA(pszSource) + 1) * sizeof(CHAR);
|
|
pszCopy = (PSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize);
|
|
if(NULL != pszCopy)
|
|
{
|
|
HRESULT hResult;
|
|
|
|
hResult = StringCbCopyA(pszCopy, dwSize, pszSource);
|
|
if(FAILED(hResult))
|
|
{
|
|
HeapFree(hHeap, 0, pszCopy);
|
|
pszCopy = NULL;
|
|
SetLastError(hResult);
|
|
}
|
|
}
|
|
|
|
return pszCopy;
|
|
}
|
|
|
|
// Frees list of strings.
|
|
// NOTE: don't use this for string list made with MakeStrPtrList(), since
|
|
// the strings pointed to be list made with MakeStrPtrList() will
|
|
// be freed when the multi-sz is freed.
|
|
void FreeStringList(HANDLE hHeap, PWSTR *ppszList, WORD wCount)
|
|
{
|
|
// Validate parameters.
|
|
if( (NULL == hHeap)
|
|
||
|
|
(NULL == ppszList)
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Free each of the strings in the list.
|
|
for(WORD wIndex = 0; wIndex < wCount; ++wIndex)
|
|
{
|
|
if(NULL != ppszList[wIndex]) HeapFree(hHeap, 0, ppszList[wIndex]);
|
|
}
|
|
|
|
// Free list.
|
|
HeapFree(hHeap, 0, ppszList);
|
|
}
|
|
|
|
|
|
// Retrieves pointer to a String resource.
|
|
HRESULT GetStringResource(HANDLE hHeap, HMODULE hModule, UINT uResource, PWSTR *ppszString)
|
|
{
|
|
int nResult;
|
|
DWORD dwSize = MAX_PATH;
|
|
PWSTR pszString = NULL;
|
|
HRESULT hrResult = S_OK;
|
|
|
|
|
|
VERBOSE(DLLTEXT("GetStringResource(%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
|
|
|
|
// Validate parameters.
|
|
if( (NULL == hHeap)
|
|
||
|
|
(NULL == ppszString)
|
|
)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// Allocate buffer for string resource from heap; let the driver clean it up.
|
|
pszString = (PWSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(WCHAR));
|
|
if(NULL == pszString)
|
|
{
|
|
ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
|
|
|
|
hrResult = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
// Load string resource; resize after loading so as not to waste memory.
|
|
nResult = LoadString(hModule, uResource, pszString, dwSize);
|
|
if(nResult > 0)
|
|
{
|
|
PWSTR pszTemp;
|
|
|
|
|
|
VERBOSE(DLLTEXT("LoadString() returned %d!\r\n"), nResult);
|
|
VERBOSE(DLLTEXT("String load was \"%s\".\r\n"), pszString);
|
|
|
|
pszTemp = (PWSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszString, (nResult + 1) * sizeof(WCHAR));
|
|
if(NULL != pszTemp)
|
|
{
|
|
pszString = pszTemp;
|
|
}
|
|
else
|
|
{
|
|
WARNING(DLLTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
|
|
|
|
ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
|
|
ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
|
|
|
|
HeapFree(hHeap, 0, pszString);
|
|
pszString = NULL;
|
|
hrResult = HRESULT_FROM_WIN32(dwError);
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
// Save string pointer to caller.
|
|
// NOTE: string pointer will be NULL on failure.
|
|
*ppszString = pszString;
|
|
|
|
return hrResult;
|
|
}
|
|
|
|
// Retrieves pointer to a String resource.
|
|
HRESULT GetStringResource(HANDLE hHeap, HMODULE hModule, UINT uResource, PSTR *ppszString)
|
|
{
|
|
int nResult;
|
|
DWORD dwSize = MAX_PATH;
|
|
PSTR pszString = NULL;
|
|
HRESULT hrResult = S_OK;
|
|
|
|
|
|
VERBOSE(DLLTEXT("GetStringResource(%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
|
|
|
|
// Validate parameters.
|
|
if( (NULL == hHeap)
|
|
||
|
|
(NULL == ppszString)
|
|
)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// Allocate buffer for string resource from heap; let the driver clean it up.
|
|
pszString = (PSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(WCHAR));
|
|
if(NULL == pszString)
|
|
{
|
|
ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
|
|
|
|
hrResult = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
// Load string resource; resize after loading so as not to waste memory.
|
|
nResult = LoadStringA(hModule, uResource, pszString, dwSize);
|
|
if(nResult > 0)
|
|
{
|
|
PSTR pszTemp;
|
|
|
|
|
|
VERBOSE(DLLTEXT("LoadString() returned %d!\r\n"), nResult);
|
|
VERBOSE(DLLTEXT("String load was \"%hs\".\r\n"), pszString);
|
|
|
|
pszTemp = (PSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszString, nResult + 1);
|
|
if(NULL != pszTemp)
|
|
{
|
|
pszString = pszTemp;
|
|
}
|
|
else
|
|
{
|
|
WARNING(DLLTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
|
|
|
|
ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
|
|
ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
|
|
|
|
HeapFree(hHeap, 0, pszString);
|
|
pszString = NULL;
|
|
hrResult = HRESULT_FROM_WIN32(dwError);
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
// Save string pointer to caller.
|
|
// NOTE: string pointer will be NULL on failure.
|
|
*ppszString = pszString;
|
|
|
|
return hrResult;
|
|
}
|
|
|