// Copyright (c)1993-1997 Microsoft Corporation, All Rights Reserved // Brian A. Moore // // This file is used for Mac only functions to assist in the Mac port of // inetcomm. // -------------------------------------------------------------------------------- #include "pch.hxx" #ifdef MAC #include "dllmain.h" #include #include "resource.h" #ifdef DEBUG #define PRIVATE #else // !DEBUG #define PRIVATE static #endif // DEBUG #define HEX_ESCAPE L'%' #define URL_ESCAPE_PERCENT 0x00001000 #define POUND L'#' #define QUERY L'?' #define TERMSTR(pch) *(pch) = L'\0' PRIVATE CONST WORD isSafe[96] = /* Bit 0 alphadigit -- 'a' to 'z', '0' to '9', 'A' to 'Z' ** Bit 1 Hex -- '0' to '9', 'a' to 'f', 'A' to 'F' ** Bit 2 valid scheme -- alphadigit | "-" | "." | "+" ** Bit 3 mark -- "%" | "$"| "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" | "," */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ // {0, 8, 0, 0, 8, 8, 0, 8, 8, 8, 8, 4, 8,12,12, 0, /* 2x !"#$%&'()*+,-./ */ // IE4 BETA1: allow + through unmolested. Should consider other options // post beta1. 12feb97 tonyci {0, 8, 0, 0, 8, 8, 0, 8, 8, 8, 8, 12, 8,12,12, 0, /* 2x !"#$%&'()*+,-./ */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 0, 8, 0, 0, /* 3x 0123456789:;<=>? */ 8, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x @ABCDEFGHIJKLMNO */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, /* 5X PQRSTUVWXYZ[\]^_ */ 0, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x `abcdefghijklmno */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 8, 0}; /* 7X pqrstuvwxyz{|}~ DEL */ PRIVATE const WCHAR hex[] = {L"0123456789ABCDEF"}; PRIVATE inline BOOL IsSafe(WCHAR ch, WORD mask) { if(ch > 31 && ch < 128 && (isSafe[ch - 32] & mask)) return TRUE; return FALSE; } #define IsAlphaDigit(c) IsSafe(c, 1) #define IsHex(c) IsSafe(c, 2) #define IsValidSchemeCharA(c) IsSafe(c, 5) #define IsSafePathChar(c) IsSafe(c, 9) ///////////////////////////////////////////////////////////////////////////// // Line Break Character Table const WCHAR MAC_awchNonBreakingAtLineEnd[] = { 0x0028, // LEFT PARENTHESIS 0x005B, // LEFT SQUARE BRACKET 0x007B, // LEFT CURLY BRACKET 0x00AB, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0x2018, // LEFT SINGLE QUOTATION MARK 0x201C, // LEFT DOUBLE QUOTATION MARK 0x2039, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x2045, // LEFT SQUARE BRACKET WITH QUILL 0x207D, // SUPERSCRIPT LEFT PARENTHESIS 0x208D, // SUBSCRIPT LEFT PARENTHESIS 0x226A, // MUCH LESS THAN 0x3008, // LEFT ANGLE BRACKET 0x300A, // LEFT DOUBLE ANGLE BRACKET 0x300C, // LEFT CORNER BRACKET 0x300E, // LEFT WHITE CORNER BRACKET 0x3010, // LEFT BLACK LENTICULAR BRACKET 0x3014, // LEFT TORTOISE SHELL BRACKET 0x3016, // LEFT WHITE LENTICULAR BRACKET 0x3018, // LEFT WHITE TORTOISE SHELL BRACKET 0x301A, // LEFT WHITE SQUARE BRACKET 0x301D, // REVERSED DOUBLE PRIME QUOTATION MARK 0xFD3E, // ORNATE LEFT PARENTHESIS 0xFE35, // PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS 0xFE37, // PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET 0xFE39, // PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET 0xFE3B, // PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET 0xFE3D, // PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET 0xFE3F, // PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET 0xFE41, // PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET 0xFE43, // PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET 0xFE59, // SMALL LEFT PARENTHESIS 0xFE5B, // SMALL LEFT CURLY BRACKET 0xFE5D, // SMALL LEFT TORTOISE SHELL BRACKET 0xFF08, // FULLWIDTH LEFT PARENTHESIS 0xFF1C, // FULLWIDTH LESS-THAN SIGN 0xFF3B, // FULLWIDTH LEFT SQUARE BRACKET 0xFF5B, // FULLWIDTH LEFT CURLY BRACKET 0xFF62, // HALFWIDTH LEFT CORNER BRACKET 0xFFE9 // HALFWIDTH LEFTWARDS ARROW }; const WCHAR MAC_awchNonBreakingAtLineStart[] = { 0x0029, // RIGHT PARENTHESIS 0x002D, // HYPHEN 0x005D, // RIGHT SQUARE BRACKET 0x007D, // RIGHT CURLY BRACKET 0x00AD, // OPTIONAL HYPHEN 0x00BB, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 0x02C7, // CARON 0x02C9, // MODIFIER LETTER MACRON 0x055D, // ARMENIAN COMMA 0x060C, // ARABIC COMMA 0x2013, // EN DASH 0x2014, // EM DASH 0x2016, // DOUBLE VERTICAL LINE 0x201D, // RIGHT DOUBLE QUOTATION MARK 0x2022, // BULLET 0x2025, // TWO DOT LEADER 0x2026, // HORIZONTAL ELLIPSIS 0x2027, // HYPHENATION POINT 0x203A, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x2046, // RIGHT SQUARE BRACKET WITH QUILL 0x207E, // SUPERSCRIPT RIGHT PARENTHESIS 0x208E, // SUBSCRIPT RIGHT PARENTHESIS 0x226B, // MUCH GREATER THAN 0x2574, // BOX DRAWINGS LIGHT LEFT 0x3001, // IDEOGRAPHIC COMMA 0x3002, // IDEOGRAPHIC FULL STOP 0x3003, // DITTO MARK 0x3005, // IDEOGRAPHIC ITERATION MARK 0x3009, // RIGHT ANGLE BRACKET 0x300B, // RIGHT DOUBLE ANGLE BRACKET 0x300D, // RIGHT CORNER BRACKET 0x300F, // RIGHT WHITE CORNER BRACKET 0x3011, // RIGHT BLACK LENTICULAR BRACKET 0x3015, // RIGHT TORTOISE SHELL BRACKET 0x3017, // RIGHT WHITE LENTICULAR BRACKET 0x3019, // RIGHT WHITE TORTOISE SHELL BRACKET 0x301B, // RIGHT WHITE SQUARE BRACKET 0x301E, // DOUBLE PRIME QUOTATION MARK 0x3041, // HIRAGANA LETTER SMALL A 0x3043, // HIRAGANA LETTER SMALL I 0x3045, // HIRAGANA LETTER SMALL U 0x3047, // HIRAGANA LETTER SMALL E 0x3049, // HIRAGANA LETTER SMALL O 0x3063, // HIRAGANA LETTER SMALL TU 0x3083, // HIRAGANA LETTER SMALL YA 0x3085, // HIRAGANA LETTER SMALL YU 0x3087, // HIRAGANA LETTER SMALL YO 0x308E, // HIRAGANA LETTER SMALL WA 0x309B, // KATAKANA-HIRAGANA VOICED SOUND MARK 0x309C, // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK 0x309D, // HIRAGANA ITERATION MARK 0x309E, // HIRAGANA VOICED ITERATION MARK 0x30A1, // KATAKANA LETTER SMALL A 0x30A3, // KATAKANA LETTER SMALL I 0x30A5, // KATAKANA LETTER SMALL U 0x30A7, // KATAKANA LETTER SMALL E 0x30A9, // KATAKANA LETTER SMALL O 0x30C3, // KATAKANA LETTER SMALL TU 0x30E3, // KATAKANA LETTER SMALL YA 0x30E5, // KATAKANA LETTER SMALL YU 0x30E7, // KATAKANA LETTER SMALL YO 0x30EE, // KATAKANA LETTER SMALL WA 0x30F5, // KATAKANA LETTER SMALL KA 0x30F6, // KATAKANA LETTER SMALL KE 0x30FC, // KATAKANA-HIRAGANA PROLONGED SOUND MARK 0x30FD, // KATAKANA ITERATION MARK 0x30FE, // KATAKANA VOICED ITERATION MARK 0xFD3F, // ORNATE RIGHT PARENTHESIS 0xFE30, // VERTICAL TWO DOT LEADER 0xFE31, // VERTICAL EM DASH 0xFE33, // VERTICAL LOW LINE 0xFE34, // VERTICAL WAVY LOW LINE 0xFE36, // PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS 0xFE38, // PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET 0xFE3A, // PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET 0xFE3C, // PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET 0xFE3E, // PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET 0xFE40, // PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET 0xFE42, // PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET 0xFE44, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET 0xFE4F, // WAVY LOW LINE 0xFE50, // SMALL COMMA 0xFE51, // SMALL IDEOGRAPHIC COMMA 0xFE5A, // SMALL RIGHT PARENTHESIS 0xFE5C, // SMALL RIGHT CURLY BRACKET 0xFE5E, // SMALL RIGHT TORTOISE SHELL BRACKET 0xFF09, // FULLWIDTH RIGHT PARENTHESIS 0xFF0C, // FULLWIDTH COMMA 0xFF0E, // FULLWIDTH FULL STOP 0xFF1E, // FULLWIDTH GREATER-THAN SIGN 0xFF3D, // FULLWIDTH RIGHT SQUARE BRACKET 0xFF40, // FULLWIDTH GRAVE ACCENT 0xFF5C, // FULLWIDTH VERTICAL LINE 0xFF5D, // FULLWIDTH RIGHT CURLY BRACKET 0xFF5E, // FULLWIDTH TILDE 0xFF61, // HALFWIDTH IDEOGRAPHIC FULL STOP 0xFF63, // HALFWIDTH RIGHT CORNER BRACKET 0xFF64, // HALFWIDTH IDEOGRAPHIC COMMA 0xFF67, // HALFWIDTH KATAKANA LETTER SMALL A 0xFF68, // HALFWIDTH KATAKANA LETTER SMALL I 0xFF69, // HALFWIDTH KATAKANA LETTER SMALL U 0xFF6A, // HALFWIDTH KATAKANA LETTER SMALL E 0xFF6B, // HALFWIDTH KATAKANA LETTER SMALL O 0xFF6C, // HALFWIDTH KATAKANA LETTER SMALL YA 0xFF6D, // HALFWIDTH KATAKANA LETTER SMALL YU 0xFF6E, // HALFWIDTH KATAKANA LETTER SMALL YO 0xFF6F, // HALFWIDTH KATAKANA LETTER SMALL TU 0xFF70, // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK 0xFF9E, // HALFWIDTH KATAKANA VOICED SOUND MARK 0xFF9F, // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK 0xFFEB // HALFWIDTH RIGHTWARDS ARROW }; const WCHAR MAC_awchRomanInterWordSpace[] = { 0x0009, // TAB 0x0020, // SPACE 0x2002, // EN SPACE 0x2003, // EM SPACE 0x2004, // THREE-PER-EM SPACE 0x2005, // FOUR-PER-EM SPACE 0x2006, // SIX-PER-EM SPACE 0x2007, // FIGURE SPACE 0x2008, // PUNCTUATION SPACE 0x2009, // THIN SPACE 0x200A, // HAIR SPACE 0x200B // ZERO WIDTH SPACE }; BOOL MAC_ScanWChar(const WCHAR awch[], int nArraySize, WCHAR wch) { int iMin = 0; int iMax = nArraySize - 1; while (iMax - iMin >= 2) { int iTry = (iMax + iMin + 1) / 2; if (wch < awch[iTry]) iMax = iTry; else if (wch > awch[iTry]) iMin = iTry; else return TRUE; } return (wch == awch[iMin] || wch == awch[iMax]); } // -------------------------------------------------------------------------------- // Mac_StrStrIA // -------------------------------------------------------------------------------- STDAPI_(LPSTR) Mac_StrStrIA(LPCSTR lpFirst, LPCSTR lpSrch) { LPSTR lpFirstI; LPSTR lpSrchI; LPSTR lpRet; if ((NULL == lpFirst) || (NULL == lpSrch)) { return NULL; } lpFirstI = StrDupA(lpFirst); lpSrchI = StrDupA(lpSrch); lpRet = StrStr(lpFirstI, lpSrchI); SafeMemFree(lpFirstI); SafeMemFree(lpSrchI); return lpRet; } // -------------------------------------------------------------------------------- // MAC_StrFormatByteSize // -------------------------------------------------------------------------------- LPSTR MAC_StrFormatByteSize(DWORD dw, LPSTR szBuf, UINT uiBufSize) { CHAR szUnit[15]; szUnit[0] = '\0'; if (dw > 1024) { LoadString(g_hLocRes, idsBytes, szUnit, ARRAYSIZE(szUnit)); _snprintf(szBuf, uiBufSize, szUnit, dw); } else { LoadString(g_hLocRes, idsKilo, szUnit, ARRAYSIZE(szUnit)); _snprintf(szBuf, uiBufSize, szUnit, (ULONG) (dw / 1024)); } return szBuf; } // -------------------------------------------------------------------------------- // MAC_PathFindExtension // -------------------------------------------------------------------------------- STDAPI_(LPSTR) MAC_PathFindExtension(LPCSTR pszPath) { LPSTR pszWalk; LPSTR pszFileName = (LPSTR) pszPath; LPSTR pszLastDot = NULL; for (pszWalk = (LPSTR) pszPath; *pszWalk != '\0'; pszWalk++) { // $REVIEW: Should we be looking for Macintosh directories // or Windows directories??? if (':' == *pszWalk) { // Point to the character after the seperator // because that might be the start of the file name pszFileName = pszWalk + 1; } else if ('.' == *pszWalk) { pszLastDot = pszWalk; } } if (pszLastDot < pszFileName) { pszLastDot = pszWalk; } return pszLastDot; } // -------------------------------------------------------------------------------- // MAC_PathFindFileName // -------------------------------------------------------------------------------- STDAPI_(LPSTR) MAC_PathFindFileName(LPCSTR pszPath) { LPSTR pszWalk; LPSTR pszFileName = (LPSTR) pszPath; for (pszWalk = (LPSTR) pszPath; *pszWalk != '\0'; pszWalk++) { // $REVIEW: Should we be looking for Macintosh directories // or Windows directories??? if (':' == *pszWalk) { // Point to the character after the seperator // because that might be the start of the file name pszFileName = pszWalk + 1; } } return pszFileName; } // -------------------------------------------------------------------------------- // MAC_BreakLineW // -------------------------------------------------------------------------------- HRESULT MAC_BreakLineW(LCID locale, const WCHAR* pszSrc, long cchSrc, long cMaxColumns, long* pcchLine, long* pcchSkip) { HRESULT hr = S_OK; long cColumns = 0; long lCandPos; long lBreakPos = -1; long lSkipLen = 0; struct { unsigned fDone : 1; unsigned fInSpaces : 1; unsigned fFEChar : 1; unsigned fInFEChar : 1; unsigned fBreakByEndOfLine : 1; unsigned fNonBreakNext : 1; unsigned fHaveCandPos : 1; unsigned fSlashR : 1; } Flags = {0, 0, 0, 0, 0, 0, 0, 0}; locale; // Not used yet... // While we still have characters left for (int iCh = 0; iCh < cchSrc; iCh++) { const WCHAR wch = pszSrc[iCh]; if (wch == wchCR && !Flags.fSlashR) { Flags.fSlashR = TRUE; } else if (wch == wchLF || Flags.fSlashR) // End of line { Flags.fDone = TRUE; Flags.fBreakByEndOfLine = TRUE; if (Flags.fInSpaces) { Flags.fHaveCandPos = FALSE; lBreakPos = lCandPos; lSkipLen++; // Skip spaces and line break character } else { lBreakPos = iCh; // Break at right before the end of line if (Flags.fSlashR) lBreakPos--; lSkipLen = 1; // Skip line break character } if (wch == wchLF && Flags.fSlashR) lSkipLen++; break; } else if (MAC_ScanWChar(MAC_awchRomanInterWordSpace, ARRAYSIZE(MAC_awchRomanInterWordSpace), wch)) // Spaces { if (!Flags.fInSpaces && !Flags.fNonBreakNext) { Flags.fHaveCandPos = TRUE; lCandPos = iCh; // Break at right before the spaces lSkipLen = 0; } Flags.fInSpaces = TRUE; lSkipLen++; // Skip continuous spaces after breaking } else // Other characters { // Don't use this code. We'll pick it up when MLANG is ported. #ifdef NEVER Flags.fFEChar = ((wCharType3 & (C3_KATAKANA | C3_HIRAGANA | C3_FULLWIDTH | C3_IDEOGRAPH)) != 0); if ((Flags.fFEChar || Flags.fInFEChar) && !Flags.fNonBreakNext && !Flags.fInSpaces) { Flags.fHaveCandPos = TRUE; lCandPos = lSrcPosTemp + iCh; // Break at right before or after the FE char lSkipLen = 0; } Flags.fInFEChar = Flags.fFEChar; #endif // NEVER Flags.fInSpaces = FALSE; if (Flags.fHaveCandPos) { Flags.fHaveCandPos = FALSE; if (!MAC_ScanWChar(MAC_awchNonBreakingAtLineStart, ARRAYSIZE(MAC_awchNonBreakingAtLineStart), wch)) lBreakPos = lCandPos; } if (cColumns + 1 > cMaxColumns) { Flags.fDone = TRUE; break; } Flags.fNonBreakNext = MAC_ScanWChar(MAC_awchNonBreakingAtLineEnd, ARRAYSIZE(MAC_awchNonBreakingAtLineEnd), wch); } cColumns++; } if (Flags.fHaveCandPos) lBreakPos = lCandPos; if (!Flags.fBreakByEndOfLine && lBreakPos < 0) { lBreakPos = min(cchSrc, cMaxColumns); // Default breaking lSkipLen = 0; } if (!Flags.fDone) { if (Flags.fInSpaces) { lBreakPos = cchSrc - lSkipLen; } else { lBreakPos = cchSrc; lSkipLen = 0; } if (Flags.fSlashR) { lBreakPos--; lSkipLen++; } } if (pcchLine) *pcchLine = lBreakPos; if (pcchSkip) *pcchSkip = lSkipLen; return hr; } // -------------------------------------------------------------------------------- // MAC_BreakLineA // -------------------------------------------------------------------------------- HRESULT MAC_BreakLineA(LCID locale, UINT uCodePage, const CHAR* pszSrc, long cchSrc, long cMaxColumns, long* pcchLine, long* pcchSkip) { HRESULT hr; LPWSTR wszBuff = NULL; long cchLineTemp; long cchSkipTemp; int cwch; // Check parameters if ((NULL == pszSrc) || (cMaxColumns < 0)) { hr = E_FAIL; goto exit; } if (0 == cchSrc) { hr = S_OK; if (pcchLine) { *pcchLine = 0; } if (pcchSkip) { *pcchSkip = 0; } goto exit; } cwch = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, pszSrc, cchSrc, NULL, NULL); if (!cwch) { hr = E_FAIL; goto exit; } CHECKALLOC(wszBuff = (LPWSTR)g_pMalloc->Alloc(cwch * sizeof(WCHAR))); cwch = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, pszSrc, cchSrc, wszBuff, cwch); Assert(cwch); CHECKHR(hr = MAC_BreakLineW(locale, wszBuff, cwch, cMaxColumns, &cchLineTemp, &cchSkipTemp)); if (pcchLine) { if (cchLineTemp != 0) { *pcchLine = WideCharToMultiByte(uCodePage, 0, wszBuff, cchLineTemp, NULL, 0, NULL, NULL); } else { *pcchLine = 0; } } if (pcchSkip) { *pcchSkip = WideCharToMultiByte(uCodePage, 0, wszBuff + cchLineTemp, cchSkipTemp, NULL, 0, NULL, NULL); } exit: SafeMemFree(wszBuff); return hr; } //--------------------------------------------------------------------------------- // MAC_IsConvertINetStringAvailable //--------------------------------------------------------------------------------- STDAPI MAC_IsConvertINetStringAvailable(DWORD dwSrcEncoding, DWORD dwDstEncoding) { HRESULT hrResult = S_OK; if (!(IsValidCodePage(dwSrcEncoding) && IsValidCodePage(dwDstEncoding))) { hrResult = S_FALSE; } return hrResult; } //--------------------------------------------------------------------------------- // MAC_ConvertINetString //--------------------------------------------------------------------------------- STDAPI MAC_ConvertINetString(LPDWORD lpdwMode, DWORD dwSrcEncoding, DWORD dwDstEncoding, LPCSTR lpSrcStr, LPINT lpnSrcSize, LPSTR lpDstStr, LPINT lpnDstSize) { HRESULT hrResult; INT cch; INT cwch; INT cchSrcSize; INT cchDstSize; LPWSTR pwsz = NULL; // Check parameters.... if (lpdwMode) { AssertSz(FALSE, "We don't support any variations"); hrResult = E_FAIL; cchDstSize = 0; goto exit; } if ((!lpSrcStr) || (FALSE == IsValidCodePage(dwSrcEncoding)) || (FALSE == IsValidCodePage(dwDstEncoding))) { hrResult = E_FAIL; cchDstSize = 0; goto exit; } if(lpnSrcSize) { cchSrcSize = *lpnSrcSize; } else { cchSrcSize = -1; } if(!lpDstStr) { cchDstSize = 0; } else if (lpnDstSize) { cchDstSize = *lpnDstSize; } else { cchDstSize = 0; } if (-1 == cchSrcSize) { AssertSz(FALSE, "We don't support any variations"); hrResult = E_FAIL; goto exit; } // Allocate the buffer hrResult = HrAlloc((LPVOID *)&pwsz, cchSrcSize * sizeof(WCHAR)); if (FAILED(hrResult)) goto exit; cwch = MultiByteToWideChar(dwSrcEncoding, MB_PRECOMPOSED, lpSrcStr, cchSrcSize, pwsz, cchSrcSize * sizeof(WCHAR)); if (0 == cwch) { hrResult = E_FAIL; goto exit; } cchDstSize = WideCharToMultiByte(dwDstEncoding, 0, pwsz, cwch, lpDstStr, cchDstSize, NULL, NULL); if (0 == cchDstSize) { hrResult = E_FAIL; goto exit; } exit: if (lpnDstSize) { *lpnDstSize = cchDstSize; } SafeMemFree(pwsz); return hrResult; } STDAPI MAC_CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pszResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved) { UINT cchSizeNeeded = 0; UINT cchBaseUrl; HRESULT hr; LPWSTR pwzTempUrl; // Check the parameters if ((!pwzBaseUrl) || dwCombineFlags || dwReserved) { hr = E_FAIL; goto exit; } // Do we have enough room for the string? cchBaseUrl = lstrlenW(pwzBaseUrl); cchSizeNeeded = cchBaseUrl + lstrlenW(pwzRelativeUrl) + 1; // Add one for the connecting '\' or subtract one if we have too many... if ((L'/' != pwzBaseUrl[cchBaseUrl]) && (L'/' != pwzRelativeUrl[0])) { cchSizeNeeded++; } else if ((L'/' == pwzBaseUrl[cchBaseUrl]) && (L'/' == pwzRelativeUrl[0])) { cchSizeNeeded--; } if (cchSizeNeeded < cchResult) { hr = E_FAIL; goto exit; } // Copy the base url wcscpy(pszResult, pwzBaseUrl); // Do we need a ending slash? if (L'/' != pwzBaseUrl[cchBaseUrl]) { pszResult[cchBaseUrl + 1] = L'/'; } // concatenate relative url wcscat(pszResult, ((L'/' == pwzRelativeUrl[0]) ? pwzRelativeUrl + 1: pwzRelativeUrl)); hr = S_OK; exit: // set count of result buffer if (pcchResult) { *pcchResult = cchSizeNeeded; } return hr; } // -------------------------------------------------------------------------------- // Mac_SzGetLocalPackedIP // -------------------------------------------------------------------------------- LPSTR Mac_SzGetLocalPackedIP(void) { return "127.0.0.1"; } // -------------------------------------------------------------------------------- // Mac_SzGetLocalHostNameForID // -------------------------------------------------------------------------------- LPSTR Mac_SzGetLocalHostNameForID(void) { return "localhost"; } /*+++ SHUrlUnescape() Unescapes a string in place. this is ok because it should never grow Parameters IN - psz string to unescape inplace dwFlags the relevant URL_* flags, Returns HRESULT - SUCCESS S_OK ERROR DOESNT error right now Helper Routines HexToWord takes a hexdigit and returns WORD with the right number or -1 IsEscapedChar looks at a ptr for "%XX" where X is a hexdigit TranslateEscapedChar translates "%XX" to an 8 bit char ---*/ PRIVATE WORD Mac_HexToWord(WCHAR ch) { if(ch >= L'0' && ch <= L'9') return (WORD) ch - L'0'; if(ch >= L'A' && ch <= L'F') return (WORD) ch - L'A' + 10; if(ch >= L'a' && ch <= L'f') return (WORD) ch - L'a' + 10; Assert(FALSE); //we have tried to use a non-hex number return (WORD) -1; } PRIVATE BOOL inline MAC_IsEscapedOctet(LPCWSTR pch) { return (pch[0] == HEX_ESCAPE && IsHex(pch[1]) && IsHex(pch[2])) ? TRUE : FALSE; } PRIVATE WCHAR MAC_TranslateEscapedOctet(LPCWSTR pch) { WCHAR ch; Assert(MAC_IsEscapedOctet(pch)); pch++; ch = (WCHAR) Mac_HexToWord(*pch++) * 16; // hi nibble ch += Mac_HexToWord(*pch); // lo nibble return ch; } HRESULT MAC_SHUrlUnescape(LPWSTR psz, DWORD dwFlags) { WCHAR *pchSrc = psz; WCHAR *pchDst = psz; BOOL fTrailByte = FALSE; while (*pchSrc) { if ((*pchSrc == POUND || *pchSrc == QUERY) && (dwFlags & URL_DONT_ESCAPE_EXTRA_INFO)) { lstrcpyW(pchDst, pchSrc); pchDst += lstrlenW(pchDst); break; } if (MAC_IsEscapedOctet(pchSrc)) { WCHAR ch = MAC_TranslateEscapedOctet(pchSrc); *pchDst++ = ch; pchSrc += 3; // enuff for "%XX" } else { *pchDst++ = *pchSrc++; } } TERMSTR(pchDst); return S_OK; } PRIVATE HRESULT MAC_CopyOutA(LPSTR pszIn, LPSTR pszOut, LPDWORD pcch) { HRESULT hr = S_OK; DWORD cch; Assert(pszIn); Assert(pszOut); Assert(pcch); cch = lstrlen(pszIn); if(*pcch > cch) lstrcpyA(pszOut, pszIn); else hr = E_POINTER; *pcch = cch + (FAILED(hr) ? 1 : 0); return hr; } STDAPI MAC_UrlUnescapeA(LPSTR pszIn, LPSTR pszOut, LPDWORD pcchOut, DWORD dwFlags) { HRESULT hr = S_OK; LPWSTR pwszIn = NULL; LPSTR pszOutT = NULL; if(pszIn) { hr = E_INVALIDARG; goto exit; } CHECKALLOC(pwszIn = PszToUnicode(CP_ACP, pszIn)); MAC_SHUrlUnescape(pwszIn, dwFlags); CHECKALLOC(pszOutT = PszToANSI(CP_ACP, pwszIn)); if(dwFlags & URL_UNESCAPE_INPLACE) { lstrcpyA(pszIn, pszOutT); } else if(pszOut && pcchOut && *pcchOut) { hr = MAC_CopyOutA(pszOutT, pszOut, pcchOut); } else hr = E_INVALIDARG; exit: // Cleanup SafeMemFree(pwszIn); SafeMemFree(pszOutT); return hr; } // -------------------------------------------------------------------------------- // CoCreateInstance // -------------------------------------------------------------------------------- STDAPI Athena_CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwContext, REFIID iid, LPVOID * ppv) { HRESULT hr; IClassFactory * pICFactory; *ppv = NULL; hr = Ares_DllGetClassObject(rclsid, IID_IClassFactory, (LPVOID *) &pICFactory); if (CLASS_E_CLASSNOTAVAILABLE == hr) { hr = Athena_DllGetClassObject(rclsid, IID_IClassFactory, (LPVOID *) &pICFactory); } if (FAILED(hr)) { goto Error; } hr = pICFactory->CreateInstance(pUnkOuter, iid, ppv); pICFactory->Release(); Error: return hr; } EXTERN_C INT CchFileTimeToLongDateTimeSz(FILETIME * pft, TCHAR * szDateTime, UINT cchStr, BOOL fNoSeconds); // // This function just goes off and uses a function in Capone to do it's work. STDAPI_(INT) MAC_CchFileTimeToDateTimeSz(FILETIME * pft, TCHAR * szDateTime, int cch, DWORD dwFlags) { Assert(dwFlags & DTM_LONGDATE); return CchFileTimeToLongDateTimeSz(pft, szDateTime, (UINT) cch, dwFlags & DTM_NOSECONDS); } #endif // MAC