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.
 
 
 
 
 
 

533 lines
15 KiB

#include "precomp.h"
// this class is used by our private wrappers to thunk unicode to ansi and take care of
// all the allocation goo. There are three constructors: use LPCWSTR if you just need
// to thunk a normal string to ansi, use LPCWSTR, LPDWORD if you need to thunk a list of
// null-terminated strings to ansi, and use DWORD if you need a buffer for an out
// parameter
class CAnsiStr
{
private:
CHAR m_szBuf[MAX_PATH];
BOOL m_fFree;
public:
LPSTR pszStr;
CAnsiStr(LPCWSTR);
CAnsiStr(LPCWSTR, LPDWORD pcchSize);
CAnsiStr(DWORD cchSize);
~CAnsiStr();
};
CAnsiStr::CAnsiStr(LPCWSTR pcwszStr)
{
if (pcwszStr == NULL)
{
m_fFree = FALSE;
pszStr = NULL;
}
else
{
DWORD cchSize = StrLenW(pcwszStr);
DWORD cbSize, dwErr;
m_fFree = (cchSize > (countof(m_szBuf) - 1));
if (m_fFree)
{
pszStr = (LPSTR)CoTaskMemAlloc(cchSize+1);
if (pszStr == NULL)
{
m_fFree = FALSE;
return;
}
else
ZeroMemory(pszStr, cchSize+1);
}
else
pszStr = m_szBuf;
cbSize = WideCharToMultiByte(CP_ACP, 0, pcwszStr, cchSize+1, pszStr, cchSize+1, NULL, NULL);
dwErr = GetLastError();
// NOTE: check to see if we fail, in which case we might be dealing with DBCS chars and
// need to reallocate or allocate
if ((cbSize == 0) && (dwErr == ERROR_INSUFFICIENT_BUFFER))
{
cbSize = WideCharToMultiByte(CP_ACP, 0, pcwszStr, cchSize+1, pszStr, 0, NULL, NULL);
if (m_fFree)
{
LPSTR pszStr2;
// need this second ptr because CoTaskMemRealloc doesn't free the old block if
// not enough mem for the new one
pszStr2 = (LPSTR)CoTaskMemRealloc(pszStr, cbSize);
if (pszStr2 == NULL)
CoTaskMemFree(pszStr);
pszStr = pszStr2;
}
else
{
m_fFree = (cbSize > countof(m_szBuf));
if (m_fFree)
pszStr = (LPSTR)CoTaskMemAlloc(cbSize);
}
if (m_fFree && (pszStr == NULL))
{
m_fFree = FALSE;
return;
}
WideCharToMultiByte(CP_ACP, 0, pcwszStr, cchSize+1, pszStr, cbSize, NULL, NULL);
}
}
}
CAnsiStr::CAnsiStr(LPCWSTR pcwszStr, LPDWORD pcchSize)
{
if (pcchSize != NULL)
*pcchSize = 0;
if (pcwszStr == NULL)
{
m_fFree = FALSE;
pszStr = NULL;
}
else
{
DWORD cchSize = 0;
DWORD cbSize, dwErr;
for (LPCWSTR pcwsz = pcwszStr; *pcwsz; )
{
DWORD cchStrSize = StrLenW(pcwsz)+1;
cchSize += cchStrSize;
pcwsz += cchStrSize;
}
m_fFree = (cchSize > (ARRAYSIZE(m_szBuf) - 1));
if (m_fFree)
{
pszStr = (LPSTR)CoTaskMemAlloc(cchSize+1);
if (pszStr == NULL)
{
m_fFree = FALSE;
return;
}
else
ZeroMemory(pszStr, cchSize+1);
}
else
pszStr = m_szBuf;
cbSize = WideCharToMultiByte(CP_ACP, 0, pcwszStr, cchSize+1, pszStr, cchSize+1, NULL, NULL);
dwErr = GetLastError();
// NOTE: check to see if we fail, in which case we might be dealing with DBCS chars and
// need to reallocate or allocate
if ((cbSize == 0) && (dwErr == ERROR_INSUFFICIENT_BUFFER))
{
cbSize = WideCharToMultiByte(CP_ACP, 0, pcwszStr, cchSize+1, pszStr, 0, NULL, NULL);
if (m_fFree)
{
LPSTR pszStr2;
// need this second ptr because CoTaskMemRealloc doesn't free the old block if
// not enough mem for the new one
pszStr2 = (LPSTR)CoTaskMemRealloc(pszStr, cbSize);
if (pszStr2 == NULL)
CoTaskMemFree(pszStr);
pszStr = pszStr2;
}
else
{
m_fFree = (cbSize > countof(m_szBuf));
if (m_fFree)
pszStr = (LPSTR)CoTaskMemAlloc(cbSize);
}
if (m_fFree && (pszStr == NULL))
{
m_fFree = FALSE;
return;
}
WideCharToMultiByte(CP_ACP, 0, pcwszStr, cchSize+1, pszStr, cbSize, NULL, NULL);
}
if (pcchSize != NULL)
*pcchSize = cchSize;
}
}
CAnsiStr::CAnsiStr(DWORD cchSize)
{
m_fFree = (cchSize > ARRAYSIZE(m_szBuf));
if (m_fFree)
{
pszStr = (LPSTR)CoTaskMemAlloc(cchSize);
if (pszStr == NULL)
{
m_fFree = FALSE;
return;
}
else
ZeroMemory(pszStr, cchSize);
}
else
{
pszStr = m_szBuf;
ZeroMemory(pszStr, cchSize);
}
}
CAnsiStr::~CAnsiStr()
{
if (m_fFree && (pszStr != NULL))
CoTaskMemFree(pszStr);
}
//------ advpack wrappers --------
// advpack is exclusively ANSI so have to thunk for UNICODE
HRESULT ExtractFilesWrapW(LPCWSTR pszCabName, LPCWSTR pszExpandDir, DWORD dwFlags,
LPCWSTR pszFileList, LPVOID lpReserved, DWORD dwReserved)
{
CAnsiStr astrFileList(pszFileList, NULL);
USES_CONVERSION;
if ((pszFileList != NULL) && (astrFileList.pszStr == NULL))
{
// class memory allocation failed
ASSERT(FALSE);
return E_OUTOFMEMORY;
}
return ExtractFiles(W2CA(pszCabName), W2CA(pszExpandDir), dwFlags,
(LPCSTR)astrFileList.pszStr, lpReserved, dwReserved);
}
HRESULT GetVersionFromFileWrapW(LPWSTR lpszFilename, LPDWORD pdwMSVer, LPDWORD pdwLSVer, BOOL bVersion)
{
USES_CONVERSION;
return GetVersionFromFile(W2A(lpszFilename), pdwMSVer, pdwLSVer, bVersion);
}
HRESULT RunSetupCommandWrapW(HWND hWnd, LPCWSTR szCmdName, LPCWSTR szInfSection, LPCWSTR szDir,
LPCWSTR lpszTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved )
{
USES_CONVERSION;
return RunSetupCommand(hWnd, W2CA(szCmdName), W2CA(szInfSection), W2CA(szDir),
W2CA(lpszTitle), phEXE, dwFlags, pvReserved);
}
//------ inseng wrappers --------
// inseng is exclusively ANSI so have to thunk for UNICODE
HRESULT CheckTrustExWrapW(LPCWSTR wszUrl, LPCWSTR wszFilename, HWND hwndForUI, BOOL bShowBadUI, DWORD dwReserved)
{
USES_CONVERSION;
return CheckTrustEx(W2CA(wszUrl), W2CA(wszFilename), hwndForUI, bShowBadUI, dwReserved);
}
// either shlwapi doesn't implement wrappers or their wrappers have limitations on these APIs
//------ kernel32 wrappers --------
// this is the equivalent of GetPrivateProfileString and should only be called if lpAppName
// and/or lpSectionName is NULL. shlwapi's wrappers doesn't handle the series of NULL-terminated
// strings
DWORD GetPrivateProfileStringW_p(LPCWSTR lpAppName, LPCWSTR lpSectionName, LPCWSTR lpDefault,
LPWSTR lpReturnedString, DWORD nSize, LPCWSTR lpFileName)
{
DWORD dwRetLen;
USES_CONVERSION;
// this occurence of GetPrivateProfileStringW is actually wrapped by shlwapi itself so
// you won't actually ever see GetPrivateProfileStringW in the import table for your module
if (IsOS(OS_NT))
dwRetLen = GetPrivateProfileStringW(lpAppName, lpSectionName, lpDefault, lpReturnedString, nSize, lpFileName);
else
{
CAnsiStr astrReturnedString(nSize);
if (astrReturnedString.pszStr == NULL)
{
// class memory allocation failed
ASSERT(FALSE);
return 0;
}
dwRetLen = GetPrivateProfileStringA(W2CA(lpAppName), W2CA(lpSectionName), W2CA(lpDefault),
astrReturnedString.pszStr, nSize, W2CA(lpFileName));
MultiByteToWideChar(CP_ACP, 0, astrReturnedString.pszStr, dwRetLen+1, lpReturnedString, nSize);
// handle possible truncation
if (((lpAppName == NULL) || (lpSectionName == NULL))
&& (dwRetLen == (nSize - 2)))
lpReturnedString[nSize - 1] = TEXT('\0');
}
return dwRetLen;
}
DWORD GetPrivateProfileSectionWrapW(LPCWSTR lpAppName, LPWSTR lpReturnedString, DWORD nSize, LPCWSTR lpFileName)
{
DWORD dwRetLen;
USES_CONVERSION;
if (IsOS(OS_NT))
dwRetLen = GetPrivateProfileSectionW(lpAppName, lpReturnedString, nSize, lpFileName);
else
{
CAnsiStr astrReturnedString(nSize);
if (astrReturnedString.pszStr == NULL)
{
// class memory allocation failed
ASSERT(FALSE);
return 0;
}
dwRetLen = GetPrivateProfileSectionA(W2CA(lpAppName), astrReturnedString.pszStr, nSize, W2CA(lpFileName));
MultiByteToWideChar(CP_ACP, 0, astrReturnedString.pszStr, dwRetLen+1, lpReturnedString, nSize);
// null terminate the end of the buffer if size is insufficient
if (dwRetLen == (nSize - 2))
lpReturnedString[nSize - 1] = TEXT('\0');
}
return dwRetLen;
}
BOOL WritePrivateProfileSectionWrapW(LPCWSTR lpAppName, LPCWSTR lpString, LPCWSTR lpFileName)
{
USES_CONVERSION;
if (IsOS(OS_NT))
return WritePrivateProfileSectionW(lpAppName, lpString, lpFileName);
else
{
CAnsiStr astrString(lpString, NULL);
return WritePrivateProfileSectionA(W2CA(lpAppName), astrString.pszStr, W2CA(lpFileName));
}
}
UINT GetDriveTypeWrapW(LPCWSTR lpRootPathName)
{
USES_CONVERSION;
if (IsOS(OS_NT))
return GetDriveTypeW(lpRootPathName);
else
return GetDriveTypeA(W2CA(lpRootPathName));
}
HANDLE OpenMutexWrapW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
{
USES_CONVERSION;
if (IsOS(OS_NT))
return OpenMutexW(dwDesiredAccess, bInheritHandle, lpName);
else
return OpenMutexA(dwDesiredAccess, bInheritHandle, W2CA(lpName));
}
//------ advapi32 wrappers --------
BOOL LookupPrivilegeValueWrapW(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid)
{
USES_CONVERSION;
if (IsOS(OS_NT))
return LookupPrivilegeValueW(lpSystemName, lpName, lpLuid);
else
return LookupPrivilegeValueA(W2CA(lpSystemName), W2CA(lpName), lpLuid);
}
LONG RegLoadKeyWrapW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile)
{
USES_CONVERSION;
if (IsOS(OS_NT))
return RegLoadKeyW(hKey, lpSubKey, lpFile);
else
return RegLoadKeyA(hKey, W2CA(lpSubKey), W2CA(lpFile));
}
LONG RegUnLoadKeyWrapW(HKEY hKey, LPCWSTR lpSubKey)
{
USES_CONVERSION;
if (IsOS(OS_NT))
return RegUnLoadKeyW(hKey, lpSubKey);
else
return RegUnLoadKeyA(hKey, W2CA(lpSubKey));
}
LONG RegSaveKeyWrapW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
USES_CONVERSION;
if (IsOS(OS_NT))
return RegSaveKeyW(hKey, lpFile, lpSecurityAttributes);
else
return RegSaveKeyA(hKey, W2CA(lpFile), lpSecurityAttributes);
}
//------ shell32 wrappers --------
int SHFileOperationW_p(LPSHFILEOPSTRUCTW lpFileOpW)
{
int iRet;
USES_CONVERSION;
if (IsOS(OS_NT))
iRet = SHFileOperationW(lpFileOpW);
else
{
SHFILEOPSTRUCTA shInfo;
CAnsiStr * pastrIn = NULL;
CAnsiStr * pastrOut = NULL;
ZeroMemory(&shInfo, sizeof(shInfo));
shInfo.fAnyOperationsAborted = lpFileOpW->fAnyOperationsAborted;
shInfo.fFlags = lpFileOpW->fFlags;
shInfo.hNameMappings = lpFileOpW->hNameMappings;
shInfo.hwnd = lpFileOpW->hwnd;
shInfo.lpszProgressTitle = W2A(lpFileOpW->lpszProgressTitle);
shInfo.wFunc = lpFileOpW->wFunc;
pastrIn = new CAnsiStr(lpFileOpW->pFrom, NULL);
if ((pastrIn == NULL) || (pastrIn->pszStr == NULL))
{
// allocation failed
ASSERT(FALSE);
return E_OUTOFMEMORY;
}
shInfo.pFrom = pastrIn->pszStr;
if (lpFileOpW->fFlags & FOF_MULTIDESTFILES)
{
pastrOut = new CAnsiStr(lpFileOpW->pTo, NULL);
if ((pastrOut == NULL) || (pastrOut->pszStr == NULL))
{
// allocation failed
ASSERT(FALSE);
return E_OUTOFMEMORY;
}
shInfo.pTo = pastrOut->pszStr;
}
else
shInfo.pTo = W2A(lpFileOpW->pTo);
iRet = SHFileOperationA(&shInfo);
if (pastrIn != NULL)
delete pastrIn;
if (pastrOut != NULL)
delete pastrOut;
}
return iRet;
}
//------ private util wrappers --------
BOOL RunAndWaitA(LPSTR pszCmd, LPCSTR pcszDir, WORD wShow, LPDWORD lpExitCode /* = NULL */)
{
PROCESS_INFORMATION pi;
STARTUPINFOA stiA;
MSG msg;
ZeroMemory(&stiA, sizeof(stiA));
stiA.cb = sizeof(stiA);
stiA.dwFlags = STARTF_USESHOWWINDOW;
stiA.wShowWindow = wShow;
USES_CONVERSION;
if (!CreateProcessA(NULL, pszCmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, pcszDir, &stiA, &pi))
return FALSE;
// wait for the process to finish
while (MsgWaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (lpExitCode)
GetExitCodeProcess(pi.hProcess, lpExitCode);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return TRUE;
}
BOOL RunAndWaitW(LPWSTR pwszCmd, LPCWSTR pcwszDir, WORD wShow, LPDWORD lpExitCode /* = NULL */)
{
PROCESS_INFORMATION pi;
STARTUPINFOW stiW;
MSG msg;
ZeroMemory(&stiW, sizeof(stiW));
stiW.cb = sizeof(stiW);
stiW.dwFlags = STARTF_USESHOWWINDOW;
stiW.wShowWindow = wShow;
USES_CONVERSION;
if (!CreateProcessW(NULL, pwszCmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, pcwszDir, &stiW, &pi))
return FALSE;
// wait for the process to finish
while (MsgWaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (lpExitCode)
GetExitCodeProcess(pi.hProcess, lpExitCode);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return TRUE;
}