windows-nt/Source/XPSP1/NT/shell/ext/mlang/attrstr.h
2020-09-26 16:20:57 +08:00

156 lines
6.6 KiB
C++

// AttrStr.h : Declaration of the CMLStrAttrStrCommon
#ifndef __ATTRSTR_H_
#define __ATTRSTR_H_
#include "mlatl.h"
#include "mlstrbuf.h"
/////////////////////////////////////////////////////////////////////////////
// CMLStrAttrStrCommon
class CMLStrAttrStrCommon
{
typedef HRESULT (CMLStrAttrStrCommon::*PFNUNLOCKPROC)(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
public:
CMLStrAttrStrCommon(void);
protected:
class CLockInfo
{
protected:
class CLockInfoEntry
{
public:
void* m_psz;
PFNUNLOCKPROC m_pfnUnlockProc;
long m_lFlags;
UINT m_uCodePage;
long m_lPos;
long m_lLen;
long m_cchPos;
long m_cchLen;
};
public:
CLockInfo(CMLStrAttrStrCommon* pCommon) : m_pCommon(pCommon)
{
m_nLockCount = 0;
m_pLockArray = NULL;
}
~CLockInfo(void)
{
UnlockAll();
}
HRESULT UnlockAll(void);
HRESULT StartLock(BOOL fWrite)
{
if (fWrite && !m_nLockCount)
m_nLockCount = -1; // Negative means write lock
else if (!fWrite && m_nLockCount >= 0)
m_nLockCount++;
else
return MLSTR_E_ACCESSDENIED;
return S_OK;
}
HRESULT EndLock(BOOL fWrite)
{
ASSERT(m_nLockCount);
if (fWrite)
m_nLockCount = 0;
else
m_nLockCount--;
return S_OK;
}
HRESULT Lock(PFNUNLOCKPROC pfnUnlockProc, long lFlags, UINT uCodePage, void* psz, long lPos, long lLen, long cchPos, long cchLen);
HRESULT Find(const void* psz, long cch, void** ppKey);
HRESULT Unlock(void* pKey, const void* psz, long cch, long* pcchActual, long* plActualLen);
long GetFlags(void* pKey) {return ((CLockInfoEntry*)pKey)->m_lFlags;}
UINT GetCodePage(void* pKey) {return ((CLockInfoEntry*)pKey)->m_uCodePage;}
long GetPos(void* pKey) {return ((CLockInfoEntry*)pKey)->m_lPos;}
long GetLen(void* pKey) {return ((CLockInfoEntry*)pKey)->m_lLen;}
long GetCChPos(void* pKey) {return ((CLockInfoEntry*)pKey)->m_cchPos;}
long GetCChLen(void* pKey) {return ((CLockInfoEntry*)pKey)->m_cchLen;}
protected:
CMLStrAttrStrCommon* const m_pCommon;
int m_nLockCount;
CLockInfoEntry* m_pLockArray;
};
class CMLStrBufStandardW : public CMLStrBufW
{
protected:
LPVOID MemAlloc(ULONG cb) {return ::CoTaskMemAlloc(cb);}
LPVOID MemRealloc(LPVOID pv, ULONG cb) {return ::CoTaskMemRealloc(pv, cb);}
void MemFree(LPVOID pv) {::CoTaskMemFree(pv);}
long RoundBufSize(long cchStr);
};
public:
class CLock
{
public:
CLock(BOOL fWrite, CMLStrAttrStrCommon* pCommon, HRESULT& hr) : m_fWrite(fWrite), m_pCommon(pCommon) {m_fLocked = (SUCCEEDED(hr) && SUCCEEDED(hr = m_pCommon->GetLockInfo()->StartLock(m_fWrite)));}
~CLock(void) {if (m_fLocked) m_pCommon->GetLockInfo()->EndLock(m_fWrite);}
HRESULT FallThrough(void) {m_fLocked = FALSE; return S_OK;} // Don't call EndLock in destructor
protected:
const BOOL m_fWrite;
CMLStrAttrStrCommon* const m_pCommon;
BOOL m_fLocked;
};
HRESULT PrepareMLStrBuf(void);
HRESULT SetStrBufCommon(void* pMLStrX, long lDestPos, long lDestLen, UINT uCodePage, IMLangStringBufW* pSrcBufW, IMLangStringBufA* pSrcBufA, long* pcchActual, long* plActualLen);
HRESULT UnlockStrCommon(const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
HRESULT CheckThread(void) {return (m_dwThreadID == ::GetCurrentThreadId()) ? S_OK : E_FAIL;}
HRESULT RegularizePosLen(long* plPos, long* plLen);
HRESULT GetLen(long cchOffset, long cchLen, long* plLen);
HRESULT GetCCh(long cchOffset, long lLen, long* pcchLen);
static HRESULT CalcLenW(const WCHAR*, long cchLen, long* plLen) {if (plLen) *plLen = cchLen; return S_OK;}
static HRESULT CalcLenA(UINT uCodePage, const CHAR*, long cchLen, long* plLen);
static HRESULT CalcCChW(const WCHAR*, long lLen, long* pcchLen) {if (pcchLen) *pcchLen = lLen; return S_OK;}
static HRESULT CalcCChA(UINT uCodePage, const CHAR*, long lLen, long* pcchLen);
static HRESULT CalcBufSizeW(long lLen, long* pcchSize) {if (pcchSize) *pcchSize = lLen; return S_OK;}
static HRESULT CalcBufSizeA(long lLen, long* pcchSize) {if (pcchSize) *pcchSize = lLen * 2; return S_OK;}
static HRESULT ConvAStrToWStr(UINT uCodePage, const CHAR* pszSrc, long cchSrc, WCHAR* pszDest, long cchDest, long* pcchActualA, long* pcchActualW, long* plActualLen);
static HRESULT ConvWStrToAStr(BOOL fCanStopAtMiddle, UINT uCodePage, const WCHAR* pszSrc, long cchSrc, CHAR* pszDest, long cchDest, long* pcchActualA, long* pcchActualW, long* plActualLen);
IMLangStringBufW* GetMLStrBufW(void) const {return m_pMLStrBufW;}
void SetMLStrBufW(IMLangStringBufW* pBuf) {m_pMLStrBufW = pBuf;}
IMLangStringBufA* GetMLStrBufA(void) const {return m_pMLStrBufA;}
void SetMLStrBufA(IMLangStringBufA* pBuf) {m_pMLStrBufA = pBuf;}
UINT GetCodePage(void) const {return m_uCodePage;}
void SetCodePage(UINT uCodePage) {m_uCodePage = uCodePage;}
long GetBufFlags(void) const {return m_lBufFlags;}
void SetBufFlags(long lBufFlags) {m_lBufFlags = lBufFlags;}
long GetBufCCh(void) const {return m_cchBuf;}
void SetBufCCh(long cchBuf) {m_cchBuf = cchBuf;}
LCID GetLocale(void) const {return m_locale;}
void SetLocale(LCID locale) {m_locale = locale;}
CLockInfo* GetLockInfo(void) {return &m_LockInfo;}
HRESULT MemAlloc(ULONG cb, void** ppv) {void* pv = ::CoTaskMemAlloc(cb); if (ppv) *ppv = pv; return (pv) ? S_OK : E_OUTOFMEMORY;}
HRESULT MemFree(void* pv) {::CoTaskMemFree(pv); return S_OK;}
HRESULT UnlockWStrDirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
HRESULT UnlockWStrIndirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
HRESULT UnlockAStrDirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
HRESULT UnlockAStrIndirect(void* pKey, const void* pszSrc, long cchSrc, long* pcchActual, long* plActualLen);
protected:
~CMLStrAttrStrCommon(void);
virtual IMLStrAttr* GetMLStrAttr(void) = 0;
DWORD m_dwThreadID;
IMLangStringBufW* m_pMLStrBufW;
IMLangStringBufA* m_pMLStrBufA;
UINT m_uCodePage;
long m_lBufFlags;
long m_cchBuf;
LCID m_locale;
CLockInfo m_LockInfo;
};
#endif //__ATTRSTR_H_