/* * C N V T . H * * Data conversion routines * * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved */ #ifndef _CNVT_H_ #define _CNVT_H_ #include #include #include #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_