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.
283 lines
7.7 KiB
283 lines
7.7 KiB
/*
|
|
* C N V T . H
|
|
*
|
|
* Data conversion routines
|
|
*
|
|
* Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
|
|
*/
|
|
|
|
#ifndef _CNVT_H_
|
|
#define _CNVT_H_
|
|
|
|
#include <ex\sz.h>
|
|
#include <crc.h>
|
|
#include <limits.h>
|
|
#define INT64_MIN 0x8000000000000000
|
|
|
|
// Error return value for CchFindChar()
|
|
//
|
|
#define INVALID_INDEX ((UINT)(-1))
|
|
|
|
// Conversion functions ------------------------------------------------------
|
|
//
|
|
UINT __fastcall CchFindChar(WCHAR, LPCWSTR, UINT);
|
|
UINT __fastcall CchSkipWhitespace(LPCWSTR, UINT);
|
|
LONG __fastcall LNumberFromParam(LPCWSTR, UINT);
|
|
|
|
HRESULT __fastcall HrHTTPDateToFileTime(LPCWSTR, FILETIME *);
|
|
HRESULT __fastcall GetFileTimeFromParam(LPCWSTR, UINT, SYSTEMTIME *);
|
|
HRESULT __fastcall GetFileDateFromParam(LPCWSTR, UINT, SYSTEMTIME *);
|
|
|
|
BOOL __fastcall FGetSystimeFromDateIso8601(LPCWSTR, SYSTEMTIME *);
|
|
BOOL __fastcall FGetDateIso8601FromSystime(SYSTEMTIME *, LPWSTR, UINT);
|
|
BOOL __fastcall FGetDateRfc1123FromSystime(SYSTEMTIME *, LPWSTR, UINT);
|
|
|
|
VOID EncodeBase64 (LPBYTE pbIn, UINT cbIn, WCHAR* pwszOut, UINT cchOut);
|
|
VOID EncodeBase64A (LPBYTE pbIn, UINT cbIn, LPBYTE pbOut, UINT cbOut, BOOL fTerminate = TRUE);
|
|
SCODE ScDecodeBase64 (WCHAR* pwszIn, UINT cchIn, LPBYTE pbOut, UINT* pcbOut);
|
|
|
|
// ------------------------------------------------------------------------
|
|
// CchNeededEncodeBase64
|
|
//
|
|
// Figure the size of the string buffer needed to encode binary data of the
|
|
// given size into a Base64 string.
|
|
// Base64 uses 4 chars out for each 3 bytes in, AND if there is ANY
|
|
// "remainder", it needs another 4 chars to encode the remainder.
|
|
// ("+2" BEFORE "/3" ensures that we count any remainder as a whole
|
|
// set of 3 bytes that need 4 chars to hold the encoding.)
|
|
//
|
|
// NOTE: This function does NOT count space for the terminating NULL.
|
|
// The caller must add one for the terminating NULL, if desired.
|
|
//
|
|
inline
|
|
UINT
|
|
CchNeededEncodeBase64 (UINT cb)
|
|
{
|
|
return (((cb + 2) / 3) * 4);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
// CbNeededDecodeBase64
|
|
//
|
|
// Figure the number of bytes of space needed to decode a Base64 string
|
|
// of length cch (NOT counting terminal NULL -- pure strlen cch here).
|
|
// This is the easy direction -- the padding is already in the cch!
|
|
//
|
|
inline
|
|
UINT
|
|
CbNeededDecodeBase64 (UINT cch)
|
|
{
|
|
return ((cch / 4) * 3);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// CopyToWideBase64
|
|
//
|
|
// Copy skinny base64 encoded string into the wide base64 encoded string
|
|
// of length equal to cb. Function assumes that there is a '\0' termination
|
|
// straight at the end that is to be copied too
|
|
//
|
|
inline
|
|
VOID CopyToWideBase64(LPCSTR psz, LPWSTR pwsz, UINT cb)
|
|
{
|
|
// Include '\0' termination
|
|
//
|
|
cb++;
|
|
|
|
// Copy all the stuff to the wide string
|
|
//
|
|
while (cb--)
|
|
{
|
|
pwsz[cb] = psz[cb];
|
|
}
|
|
}
|
|
|
|
//$REVIEW: The following three do not really does not belong to any common libraries
|
|
//$REVIEW: that are shared by davex, exdav, exoledb and exprox.
|
|
//$REVIEW: On the other hand, we definitely don't want add a new lib for this. so just
|
|
//$REVIEW: add it here. Feel free to move them to a better location if you find one
|
|
//
|
|
// Routines to fetch and manipulate security IDs (SIDs)
|
|
//
|
|
SCODE
|
|
ScDupPsid (PSID psidSrc,
|
|
DWORD dwcbSID,
|
|
PSID * ppsidDst);
|
|
|
|
SCODE
|
|
ScGetTokenInfo (HANDLE hTokenUser,
|
|
DWORD * pdwcbSIDUser,
|
|
PSID * ppsidUser);
|
|
|
|
// CRCSid: A SID based key.
|
|
//
|
|
class CRCSid
|
|
{
|
|
public:
|
|
|
|
DWORD m_dwCRC;
|
|
DWORD m_dwLength;
|
|
PSID m_psid;
|
|
|
|
CRCSid (PSID psid)
|
|
: m_psid(psid)
|
|
{
|
|
UCHAR* puch;
|
|
Assert (psid);
|
|
|
|
// "Right way" -- since MSDN says not to touch the SID directly.
|
|
puch = GetSidSubAuthorityCount (psid);
|
|
m_dwLength = GetSidLengthRequired (*puch); // "cannot fail" -- MSDN
|
|
Assert (m_dwLength); // MSDN said this call "cannot fail".
|
|
|
|
m_dwCRC = DwComputeCRC (0,
|
|
psid,
|
|
m_dwLength);
|
|
}
|
|
|
|
// operators for use with the hash cache
|
|
//
|
|
int hash (const int rhs) const
|
|
{
|
|
return (m_dwCRC % rhs);
|
|
}
|
|
|
|
bool isequal (const CRCSid& rhs) const
|
|
{
|
|
return ((m_dwCRC == rhs.m_dwCRC) &&
|
|
(m_dwLength == rhs.m_dwLength) &&
|
|
!memcmp (m_psid, rhs.m_psid, m_dwLength));
|
|
}
|
|
};
|
|
|
|
//$REVIEW: These functions are needed by _storext, exdav and davex. They have
|
|
// moved quite a bit, going from calcprops.cpp to exprops.cpp and now to
|
|
// cnvt.cpp. cnvt.cpp seems to be a better destination for them than
|
|
// exprops.cpp. I bet these functions look awfully similar to some of
|
|
// the ones already in this file:-)
|
|
//
|
|
SCODE ScUnstringizeData (
|
|
IN LPCSTR pchData,
|
|
IN UINT cchData,
|
|
IN OUT BYTE * pb,
|
|
IN OUT UINT * pcb);
|
|
|
|
SCODE
|
|
ScStringizeData (IN const BYTE * pb,
|
|
IN const UINT cb,
|
|
OUT LPSTR psz,
|
|
IN OUT UINT * pcch);
|
|
|
|
SCODE
|
|
ScStringizeDataW ( IN const BYTE * pb,
|
|
IN const UINT cb,
|
|
OUT LPWSTR pwsz,
|
|
IN OUT UINT * pcch);
|
|
|
|
inline
|
|
BOOL
|
|
FCharInHexRange (char ch)
|
|
{
|
|
return ((ch >= '0' && ch <= '9') ||
|
|
(ch >= 'A' && ch <= 'F') ||
|
|
(ch >= 'a' && ch <= 'f'));
|
|
}
|
|
|
|
// Our own version of WideCharToMultiByte(CP_UTF8, ...)
|
|
//
|
|
// It returns similarly to the system call WideCharToMultiByte:
|
|
//
|
|
// If the function succeeds, and cbMulti is nonzero, the return value is
|
|
// the number of bytes written to the buffer pointed to by psz.
|
|
//
|
|
// If the function succeeds, and cbMulti is zero, the return value is
|
|
// the required size, in bytes, for a buffer that can receive the translated
|
|
// string.
|
|
//
|
|
// If the function fails, the return value is zero. To get extended error
|
|
// information, call GetLastError. GetLastError may return one of the
|
|
// following error codes:
|
|
//
|
|
// ERROR_INSUFFICIENT_BUFFER
|
|
// ERROR_INVALID_FLAGS
|
|
// ERROR_INVALID_PARAMETER
|
|
//
|
|
// See the WideCharToMultiByte MSDN pages to find out more about
|
|
// this function and its use. The only difference is that INVALID_INDEX
|
|
// should be used instead of -1.
|
|
//
|
|
UINT WideCharToUTF8(/* [in] */ LPCWSTR pwsz,
|
|
/* [in] */ UINT cchWide,
|
|
/* [out] */ LPSTR psz,
|
|
/* [in] */ UINT cbMulti);
|
|
|
|
//$ REVIEW: negative values of _int64 seem to have problems in
|
|
// the __i64toa() API. Handle those cases ourselves by using the wrapper
|
|
// function Int64ToPsz.
|
|
//
|
|
inline
|
|
VOID
|
|
Int64ToPsz (UNALIGNED __int64 * pI64, LPSTR pszBuf, UINT cbBuf)
|
|
{
|
|
Assert(pI64);
|
|
Assert(pszBuf);
|
|
Assert(cbBuf >= 64);
|
|
BOOL fNegative = (*pI64 < 0);
|
|
|
|
// Note: this workaround works for all cases except the
|
|
// most negative _int64 value (because it can't be inverted).
|
|
// Luckily __i64toa works for this case...
|
|
//
|
|
if (INT64_MIN == *pI64)
|
|
fNegative = FALSE;
|
|
|
|
if (fNegative)
|
|
{
|
|
// Stuff a negative sign into the buffer and
|
|
// then fix the value.
|
|
//
|
|
pszBuf[0] = '-';
|
|
*pI64 = 0 - *pI64;
|
|
}
|
|
|
|
Assert ((0 == fNegative) || (1 == fNegative));
|
|
_i64toa (*pI64, pszBuf + fNegative, 10);
|
|
}
|
|
|
|
//$ REVIEW: negative values of _int64 seem to have problems in
|
|
// the __i64tow() API. Handle those cases ourselves by using the wrapper
|
|
// function Int64ToPwsz.
|
|
//
|
|
inline
|
|
VOID
|
|
Int64ToPwsz (UNALIGNED __int64 * pI64, LPWSTR pwszBuf, UINT cbBuf)
|
|
{
|
|
Assert(pI64);
|
|
Assert(pwszBuf);
|
|
Assert(cbBuf >= 64 * sizeof(WCHAR));
|
|
|
|
BOOL fNegative = (*pI64 < 0);
|
|
|
|
// Note: this workaround works for all cases except the
|
|
// most negative _int64 value (because it can't be inverted).
|
|
// Luckily __i64tow works for this case...
|
|
//
|
|
if (INT64_MIN == *pI64)
|
|
fNegative = FALSE;
|
|
|
|
if (fNegative)
|
|
{
|
|
// Stuff a negative sign into the buffer and
|
|
// then fix the value.
|
|
//
|
|
pwszBuf[0] = L'-';
|
|
*pI64 = 0 - *pI64;
|
|
}
|
|
|
|
Assert ((0 == fNegative) || (1 == fNegative));
|
|
_i64tow (*pI64, pwszBuf + fNegative, 10);
|
|
}
|
|
|
|
|
|
#endif // _CNVT_H_
|