|
|
// --------------------------------------------------------------------------
// Strutil.cpp
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
// Steven J. Bailey
// --------------------------------------------------------------------------
#include "pch.hxx"
#include <iert.h>
#include "dllmain.h"
#include "oertpriv.h"
#include <wininet.h>
#include <shlwapi.h>
#include <shlwapip.h>
#include <qstrcmpi.h>
#include <shlwapi.h>
#include "unicnvrt.h"
#include <BadStrFunctions.h>
// conversion from 'int' to 'unsigned short', possible loss of data
#pragma warning (disable:4244)
// --------------------------------------------------------------------------
// g_szMonths
// --------------------------------------------------------------------------
static const LPSTR g_szMonths[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
// --------------------------------------------------------------------------
// g_szDays
// --------------------------------------------------------------------------
static const LPSTR g_szDays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
// --------------------------------------------------------------------------
// g_rgZones
// --------------------------------------------------------------------------
static const INETTIMEZONE g_rgZones[] = { { "UT", 0, 0 }, { "GMT", 0, 0 }, { "EST", 5, 0 }, { "EDT", 4, 0 }, { "CST", 6, 0 }, { "CDT", 5, 0 }, { "MST", 7, 0 }, { "MDT", 6, 0 }, { "PST", 8, 0 }, { "PDT", 7, 0 }, { "KST", -9, 0 }, { "JST", -9, 0 }, { NULL, 0, 0 } };
// --------------------------------------------------------------------------------
// How big is the thread local storage string buffer
// -------------------------------------------------------------------------------
#define CBMAX_THREAD_TLS_BUFFER 512
// --------------------------------------------------------------------------------
// ThreadAllocateTlsMsgBuffer
// -------------------------------------------------------------------------------
void ThreadAllocateTlsMsgBuffer(void) { if (g_dwTlsMsgBuffIndex != 0xffffffff) TlsSetValue(g_dwTlsMsgBuffIndex, NULL); }
// --------------------------------------------------------------------------------
// ThreadFreeTlsMsgBuffer
// -------------------------------------------------------------------------------
void ThreadFreeTlsMsgBuffer(void) { if (g_dwTlsMsgBuffIndex != 0xffffffff) { LPSTR psz = (LPSTR)TlsGetValue(g_dwTlsMsgBuffIndex); SafeMemFree(psz); SideAssert(0 != TlsSetValue(g_dwTlsMsgBuffIndex, NULL)); } }
// --------------------------------------------------------------------------------
// PszGetTlsBuffer
// -------------------------------------------------------------------------------
LPSTR PszGetTlsBuffer(void) { // Get the buffer
LPSTR pszBuffer = (LPSTR)TlsGetValue(g_dwTlsMsgBuffIndex);
// If buffer has not been allocated
if (NULL == pszBuffer) { // Allocate it
pszBuffer = (LPSTR)g_pMalloc->Alloc(CBMAX_THREAD_TLS_BUFFER);
// Store it
Assert(pszBuffer); SideAssert(0 != TlsSetValue(g_dwTlsMsgBuffIndex, pszBuffer)); }
// Done
return pszBuffer; }
// --------------------------------------------------------------------------------
// _MSG - Used to build a string from variable length args, thread-safe
// -------------------------------------------------------------------------------
OESTDAPI_(LPCSTR) _MSG(LPSTR pszFormat, ...) { // Locals
va_list arglist; LPSTR pszBuffer=NULL;
// I use tls to hold the buffer
if (g_dwTlsMsgBuffIndex != 0xffffffff) { // Setup the arglist
va_start(arglist, pszFormat);
// Get the Buffer
pszBuffer = PszGetTlsBuffer();
// If we have a buffer
if (pszBuffer) { // Format the data
wvnsprintf(pszBuffer, (CBMAX_THREAD_TLS_BUFFER - sizeof(pszBuffer[0])), pszFormat, arglist); }
// End the arglist
va_end(arglist); }
return ((LPCSTR)pszBuffer); }
// --------------------------------------------------------------------------
// StrChrExA
// --------------------------------------------------------------------------
OESTDAPI_(LPCSTR) StrChrExA(UINT codepage, LPCSTR pszString, CHAR ch) { // Locals
LPSTR pszT=(LPSTR)pszString;
// Loop for ch in pszString
while(*pszT) { // Lead Byte
if (IsDBCSLeadByteEx(codepage, *pszT)) pszT++; else if (*pszT == ch) return pszT; pszT++; }
// Not Found
return NULL; }
// --------------------------------------------------------------------------
// PszDayFromIndex
// --------------------------------------------------------------------------
OESTDAPI_(LPCSTR) PszDayFromIndex(ULONG ulIndex) { // Invalid Arg
Assert(ulIndex <= 6);
// Adjust ulIndex
ulIndex = (ulIndex > 6) ? 0 : ulIndex;
// Return
return g_szDays[ulIndex]; }
// --------------------------------------------------------------------------
// PszMonthFromIndex (ulIndex is one-based)
// --------------------------------------------------------------------------
OESTDAPI_(LPCSTR) PszMonthFromIndex(ULONG ulIndex) { // Invalid Arg
Assert(ulIndex >= 1 && ulIndex <= 12);
// Adjust ulIndex
ulIndex = (ulIndex < 1 || ulIndex > 12) ? 0 : ulIndex - 1;
// Return
return g_szMonths[ulIndex]; }
// --------------------------------------------------------------------------
// HrFindInetTimeZone
// --------------------------------------------------------------------------
OESTDAPI_(HRESULT) HrFindInetTimeZone(LPCSTR pszTimeZone, LPINETTIMEZONE pTimeZone) { // Invalid Arg
Assert(pszTimeZone && pTimeZone);
// Loop timezone table
for (ULONG iZoneCode=0; g_rgZones[iZoneCode].lpszZoneCode!=NULL; iZoneCode++) { // Is this the code...
if (lstrcmpi(pszTimeZone, g_rgZones[iZoneCode].lpszZoneCode) == 0) { CopyMemory(pTimeZone, &g_rgZones[iZoneCode], sizeof(INETTIMEZONE)); return S_OK; } }
// Not Found
return E_FAIL; }
// --------------------------------------------------------------------------
// HrIndexOfMonth
// --------------------------------------------------------------------------
OESTDAPI_(HRESULT) HrIndexOfMonth(LPCSTR pszMonth, ULONG *pulIndex) { // Invalid Arg
Assert(pszMonth && pulIndex);
// Loop the Months
for (ULONG iMonth=0; iMonth < ARRAYSIZE(g_szMonths); iMonth++) { // Is this the month
if (OEMstrcmpi(pszMonth, g_szMonths[iMonth]) == 0) { // Set It
*pulIndex = (iMonth + 1);
// Validate
AssertSz(*pulIndex >= 1 && *pulIndex <= 12, "HrIndexOfMonth - Bad Month");
// Done
return S_OK; } }
*pulIndex = 0;
// Not Found
return E_FAIL; }
// --------------------------------------------------------------------------
// HrIndexOfWeek
// --------------------------------------------------------------------------
OESTDAPI_(HRESULT) HrIndexOfWeek(LPCSTR pszDay, ULONG *pulIndex) { // Invalid Arg
Assert(pszDay && pulIndex);
// Loop the Days
for (ULONG iDayOfWeek=0; iDayOfWeek < ARRAYSIZE(g_szDays); iDayOfWeek++) { // Is this the day
if (OEMstrcmpi(pszDay, g_szDays[iDayOfWeek]) == 0) { // Set Day Of Week
*pulIndex = iDayOfWeek;
// Validate
AssertSz(((int) *pulIndex) >= 0 && ((int) *pulIndex) <= 6, "HrIndexOfDay - Bad day of week");
// Done
return S_OK; } }
*pulIndex = 0;
// Failure
return E_FAIL; }
// --------------------------------------------------------------------------
// PszEscapeMenuStringA
//
// Escapes & characters with another & so that they show up correctly when shown
// in a menu.
// --------------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszEscapeMenuStringA(LPCSTR pszSource, LPSTR pszQuoted, int cchMax) { LPSTR pszT=pszQuoted; int cch = 1; // 1 is intentional
Assert(pszSource); Assert(pszQuoted);
while((cch < cchMax) && (*pszSource)) { if (IsDBCSLeadByte(*pszSource)) { cch++; // Is there only space for lead byte?
if (cch == cchMax) // Yes, don't write it
break; else *pszT++ = *pszSource++; } else if ('&' == *pszSource) { cch++; if (cch == cchMax) break; else *pszT++ = '&'; }
// Only way this could fail is if there was a DBCSLeadByte with no trail byte
Assert(*pszSource);
*pszT++ = *pszSource++; cch++; } *pszT = 0;
return pszQuoted; }
// --------------------------------------------------------------------------------
// PszSkipWhiteA
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszSkipWhiteA(LPSTR psz) { while(*psz && (*psz == ' ' || *psz == '\t')) psz++; return psz; }
OESTDAPI_(LPWSTR) PszSkipWhiteW(LPWSTR psz) { while(*psz && (*psz == L' ' || *psz == L'\t')) psz++; return psz; }
// --------------------------------------------------------------------------
// PszScanToWhiteA
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszScanToWhiteA(LPSTR psz) { while(*psz && ' ' != *psz && '\t' != *psz) psz++; return psz; }
// --------------------------------------------------------------------------
// PszScanToCharA
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszScanToCharA(LPSTR psz, CHAR ch) { while(*psz && ch != *psz) psz++; return psz; }
// --------------------------------------------------------------------------
// PszDupLenA
// duplicates a string with upto cchMax characters in (and a null term)
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszDupLenA(LPCSTR pcszSource, int cchMax) { // Locals
LPSTR pszDup=NULL;
// No Source
if (pcszSource == NULL || cchMax == 0) goto exit;
// the amount to copy if the min of the max and the
// source
cchMax = min(lstrlen(pcszSource), cchMax);
// Allocate the String
pszDup = PszAllocA(cchMax+1); // +1 for null term
if (!pszDup) goto exit;
// Copy the data, leave room for the null-term
CopyMemory(pszDup, pcszSource, cchMax);
// null terminate
pszDup[cchMax] = 0;
exit: // Done
return pszDup; }
// --------------------------------------------------------------------------
// PszFromANSIStreamA - pstm is assumed to be an ANSI stream
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszFromANSIStreamA(LPSTREAM pstm) { // Locals
HRESULT hr; LPSTR psz=NULL; ULONG cb;
// Get stream size
hr = HrGetStreamSize(pstm, &cb); if (FAILED(hr)) { Assert(FALSE); return NULL; }
// Rewind the stream
HrRewindStream(pstm);
// Allocate a buffer
if ((psz = PszAllocA(cb + 1)) != NULL) { // Read a buffer from stream
hr = pstm->Read(psz, cb, NULL); if (FAILED(hr)) { Assert(FALSE); MemFree(psz); return NULL; }
// Null Terminate
*(psz + cb) = '\0'; }
// Done
return psz; }
// --------------------------------------------------------------------------
// PszFromANSIStreamW - pstm is assumed to be an ANSI stream
// --------------------------------------------------------------------------
LPWSTR PszFromANSIStreamW(UINT cp, LPSTREAM pstm) { // Get ANSI string
LPSTR psz = PszFromANSIStreamA(pstm); if (NULL == psz) return NULL;
// Convert to unicode
LPWSTR pwsz = PszToUnicode(cp, psz); // Done
return pwsz; }
// --------------------------------------------------------------------------
// ConvertFromHex - Converts a hexdigit into a numerica value
// --------------------------------------------------------------------------
OESTDAPI_(CHAR) ChConvertFromHex (CHAR ch) { if (ch >= '0' && ch <= '9') return CHAR((ch - '0'));
else if (ch >= 'A'&& ch <= 'F') return CHAR(((ch - 'A') + 10));
else if (ch >= 'a' && ch <= 'f') return CHAR(((ch - 'a') + 10));
else return ((CHAR)(BYTE)255); }
// --------------------------------------------------------------------------
// FIsValidRegKeyNameA
// --------------------------------------------------------------------------
BOOL FIsValidRegKeyNameA(LPSTR pszKey) { // Locals
LPSTR psz=pszKey;
// If Empty...
if (FIsEmptyA(pszKey)) return FALSE;
// Check for backslashes
while(*psz) { if (*psz == '\\') return FALSE; psz = CharNextA(psz); }
// Its ok
return TRUE; }
// --------------------------------------------------------------------------
// FIsValidRegKeyNameW
// --------------------------------------------------------------------------
BOOL FIsValidRegKeyNameW(LPWSTR pwszKey) { // Locals
LPWSTR pwsz=pwszKey;
// If Empty...
if (FIsEmptyW(pwszKey)) return FALSE;
// Check for backslashes
while(*pwsz) { if (*pwsz == L'\\') return FALSE; pwsz = CharNextW(pwsz); }
// Its ok
return TRUE; }
// --------------------------------------------------------------------------
// FIsSpaceA
// --------------------------------------------------------------------------
OESTDAPI_(BOOL) FIsSpaceA(LPSTR psz) { WORD wType = 0;
if (IsDBCSLeadByte(*psz)) SideAssert(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); else SideAssert(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); return (wType & C1_SPACE); }
// --------------------------------------------------------------------------
// FIsSpaceW
// --------------------------------------------------------------------------
OESTDAPI_(BOOL) FIsSpaceW(LPWSTR pwsz) { BOOL result = FALSE;
if (S_OK == IsPlatformWinNT()) { WORD wType = 0; SideAssert(GetStringTypeExW(LOCALE_USER_DEFAULT, CT_CTYPE1, pwsz, 1, &wType)); result = (wType & C1_SPACE); } else { LPSTR psz = PszToANSI(CP_ACP, pwsz); if (psz) result = FIsSpaceA(psz); MemFree(psz); }
return result; }
// --------------------------------------------------------------------------
// FIsEmptyA
// --------------------------------------------------------------------------
OESTDAPI_(BOOL) FIsEmptyA(LPCSTR pcszString) { // Locals
LPSTR psz;
// Bad Pointer
if (!pcszString) return TRUE;
// Check for All spaces
psz = (LPSTR)pcszString; while (*psz) { if (FIsSpaceA(psz) == FALSE) return FALSE; psz++; }
// Done
return TRUE; }
// --------------------------------------------------------------------------
// FIsEmptyW
// --------------------------------------------------------------------------
OESTDAPI_(BOOL) FIsEmptyW(LPCWSTR pcwszString) { // Locals
LPWSTR pwsz;
// Bad Pointer
if (!pcwszString) return TRUE;
// Check for All spaces
pwsz = (LPWSTR)pcwszString; while (*pwsz) { if (FIsSpaceW(pwsz) == FALSE) return FALSE; pwsz++; }
// Done
return TRUE; }
// --------------------------------------------------------------------------
// PszAllocA
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszAllocA(INT nLen) { // Locals
LPSTR psz=NULL;
// Empty ?
if (nLen == 0) goto exit;
// Allocate
if (FAILED(HrAlloc((LPVOID *)&psz, (nLen + 1) * sizeof (CHAR)))) goto exit; exit: // Done
return psz; }
// --------------------------------------------------------------------------
// PszAllocW
// --------------------------------------------------------------------------
OESTDAPI_(LPWSTR) PszAllocW(INT nLen) { // Locals
LPWSTR pwsz=NULL;
// Empty ?
if (nLen == 0) goto exit;
// Allocate
if (FAILED(HrAlloc((LPVOID *)&pwsz, (nLen + 1) * sizeof (WCHAR)))) goto exit; exit: // Done
return pwsz; }
// --------------------------------------------------------------------------
// PszToUnicode
// --------------------------------------------------------------------------
OESTDAPI_(LPWSTR) PszToUnicode(UINT cp, LPCSTR pcszSource) { // Locals
INT cchNarrow, cchWide; LPWSTR pwszDup=NULL;
// No Source
if (pcszSource == NULL) goto exit;
// Length
cchNarrow = lstrlenA(pcszSource) + 1;
// Determine how much space is needed for translated widechar
cchWide = MultiByteToWideChar(cp, MB_PRECOMPOSED, pcszSource, cchNarrow, NULL, 0);
// Error
if (cchWide == 0) goto exit;
// Alloc temp buffer
pwszDup = PszAllocW(cchWide + 1); if (!pwszDup) goto exit;
// Do the actual translation
cchWide = MultiByteToWideChar(cp, MB_PRECOMPOSED, pcszSource, cchNarrow, pwszDup, cchWide+1);
// Error
if (cchWide == 0) { SafeMemFree(pwszDup); goto exit; }
exit: // Done
return pwszDup; }
// --------------------------------------------------------------------------
// PszToANSI
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszToANSI(UINT cp, LPCWSTR pcwszSource) { // Locals
INT cchNarrow, cchWide; LPSTR pszDup=NULL;
// No Source
if (pcwszSource == NULL) goto exit;
// Length
cchWide = lstrlenW(pcwszSource)+1;
// Determine how much space is needed for translated widechar
cchNarrow = WideCharToMultiByte(cp, 0, pcwszSource, cchWide, NULL, 0, NULL, NULL);
// Error
if (cchNarrow == 0) goto exit;
// Alloc temp buffer
pszDup = PszAllocA(cchNarrow + 1); if (!pszDup) goto exit;
// Do the actual translation
cchNarrow = WideCharToMultiByte(cp, 0, pcwszSource, cchWide, pszDup, cchNarrow+1, NULL, NULL);
// Error
if (cchNarrow == 0) { SafeMemFree(pszDup); goto exit; }
exit: // Done
return pszDup; }
// --------------------------------------------------------------------------
// PszDupA
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) PszDupA(LPCSTR pcszSource) { // Locals
INT nLen; LPSTR pszDup=NULL;
// No Source
if (pcszSource == NULL) goto exit;
// Get String Length
nLen = lstrlenA(pcszSource) + 1;
// Allocate the String
pszDup = PszAllocA(nLen); if (!pszDup) goto exit;
// Copy the data
CopyMemory(pszDup, pcszSource, nLen);
exit: // Done
return pszDup; }
// --------------------------------------------------------------------------
// PszDupW
// --------------------------------------------------------------------------
OESTDAPI_(LPWSTR) PszDupW(LPCWSTR pcwszSource) { // Locals
INT nLen; LPWSTR pwszDup=NULL;
// No Source
if (pcwszSource == NULL) goto exit;
// Get String Length
nLen = lstrlenW(pcwszSource) + 1;
// Allocate the String
pwszDup = PszAllocW(nLen); if (!pwszDup) goto exit;
// Copy the data
CopyMemory(pwszDup, pcwszSource, nLen * sizeof(WCHAR));
exit: // Done
return pwszDup; }
// --------------------------------------------------------------------------
// StripCRLF
// --------------------------------------------------------------------------
OESTDAPI_(void) StripCRLF(LPSTR lpsz, ULONG *pcb) { // Null ?
AssertSz (lpsz && pcb, "NULL Parameter");
// If length is zero, then return
if (!lpsz || !pcb || (*pcb == 0)) { Assert(0); return; }
// Check last three characters of the string, last char might or might not be a null-term
LONG iLast = (*pcb) - 2; if (iLast < 0) iLast = 0; for (LONG i=(*pcb); i>=iLast; i--) { // Is end character a '\n'
if (lpsz[i] == chLF) { lpsz[i] = '\0'; (*pcb)--; }
// Is end character a '\r'
if (lpsz[i] == chCR) { lpsz[i] = '\0'; (*pcb)--; } } return; }
// --------------------------------------------------------------------------
// ToUpper
// --------------------------------------------------------------------------
TCHAR ToUpper(TCHAR c) { return (TCHAR)LOWORD(CharUpper(MAKEINTRESOURCE(c))); }
// --------------------------------------------------------------------------
// IsPrint
// --------------------------------------------------------------------------
OESTDAPI_(int) IsPrint(LPSTR psz) { WORD wType; if (IsDBCSLeadByte(*psz)) SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); else SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); return !(wType & C1_CNTRL); }
// --------------------------------------------------------------------------
// IsDigit
// --------------------------------------------------------------------------
OESTDAPI_(int) IsDigit(LPSTR psz) { WORD wType; if (IsDBCSLeadByte(*psz)) SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); else SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); return (wType & C1_DIGIT); }
// --------------------------------------------------------------------------
// IsXDigit
// --------------------------------------------------------------------------
int IsXDigit(LPSTR psz) { WORD wType; if (IsDBCSLeadByte(*psz)) SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); else SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); return (wType & C1_XDIGIT); }
// --------------------------------------------------------------------------
// IsUpper
// --------------------------------------------------------------------------
OESTDAPI_(INT) IsUpper(LPSTR psz) { WORD wType; if (IsDBCSLeadByte(*psz)) SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); else SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); return (wType & C1_UPPER); }
// --------------------------------------------------------------------------
// IsAlpha
// --------------------------------------------------------------------------
int IsAlpha(LPSTR psz) { WORD wType; if (IsDBCSLeadByte(*psz)) SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); else SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); return (wType & C1_ALPHA); }
// --------------------------------------------------------------------------
// IsPunct
// --------------------------------------------------------------------------
int IsPunct(LPSTR psz) { WORD wType; if (IsDBCSLeadByte(*psz)) SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); else SideAssert(GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); return (wType & C1_PUNCT); }
// --------------------------------------------------------------------------
// strsave
// --------------------------------------------------------------------------
char *strsave(char *s) { char *p;
if (!s) return NULL;
DWORD cchSize = (lstrlen(s)+1); if (MemAlloc((LPVOID*)&p, cchSize * sizeof(p[0]))) { StrCpyN(p, s, cchSize); }
return p; }
// --------------------------------------------------------------------------
// strtrim
// --------------------------------------------------------------------------
OESTDAPI_(LPSTR) strtrim(char *s) { char *p;
for (p = s; *p; p++) ; for (--p ; (p>=s) && StrChr(" \t\r\n",*p); --p) *p = '\0'; while (*s && StrChr(" \t\r\n",*s)) ++s; return s; }
OESTDAPI_(LPWSTR) strtrimW(WCHAR *s) { WCHAR *p;
for (p = s; *p; p++) ; for (--p ; (p>=s) && StrChrW(L" \t\r\n",*p); --p) *p = '\0'; while (*s && StrChrW(L" \t\r\n",*s)) ++s; return s; }
// --------------------------------------------------------------------------
// strappend
// --------------------------------------------------------------------------
void strappend(char **pp, char *s) { char *p; Assert(pp); if (!s) return; if (!*pp) { DWORD cchSize = (lstrlen(s)+1); if (!MemAlloc((LPVOID*)&p, cchSize * sizeof(p[0]))) return; StrCpyNA(p, s, cchSize); } else { DWORD cchSize = (lstrlen(s) + lstrlen(*pp) + 2); if (!MemAlloc((LPVOID*)&p, cchSize * sizeof(p[0]))) return; StrCpyNA(p, *pp, cchSize); StrCatBuffA(p, "\r", cchSize); StrCatBuffA(p, s, cchSize); MemFree(*pp); } *pp = p; }
OESTDAPI_(ULONG) UlStripWhitespace(LPTSTR lpsz, BOOL fLeading, BOOL fTrailing, ULONG *pcb) { // Locals
ULONG cb; LPTSTR psz; Assert(lpsz != NULL); Assert(fLeading || fTrailing);
// Did the user pass in the length
if (pcb) cb = *pcb; else cb = lstrlen (lpsz);
if (cb == 0) return cb;
if (fLeading) { psz = lpsz; while (FIsSpace(psz)) { psz++; cb--; } if (psz != lpsz) // get the NULL at the end too
MoveMemory(lpsz, psz, (cb + 1) * sizeof(TCHAR)); } if (fTrailing) { psz = lpsz + cb; while (cb > 0) { if (!FIsSpace(psz-1)) break; psz--; cb--; } // NULL Term
*psz = '\0'; } // Set String Size
if (pcb) *pcb = cb; // Done
return cb; }
OESTDAPI_(ULONG) UlStripWhitespaceW(LPWSTR lpwsz, BOOL fLeading, BOOL fTrailing, ULONG *pcb) { // Locals
ULONG cb; LPWSTR pwsz; Assert(lpwsz != NULL); Assert(fLeading || fTrailing); // Did the user pass in the length
if (pcb) cb = *pcb; else cb = lstrlenW(lpwsz)* sizeof(WCHAR) ; // multiply by sizeof(WCHAR) to get correct byte size.
if (cb == 0) return cb; if (fLeading) { pwsz = lpwsz; while (FIsSpaceW(pwsz)) { pwsz++; cb -= sizeof(*pwsz); } if (pwsz != lpwsz) // get the NULL at the end too
MoveMemory(lpwsz, pwsz, cb + sizeof(WCHAR)); } if (fTrailing) { pwsz = lpwsz + cb / sizeof(WCHAR); // Divided by size of WCHAR to get right pointer
while (cb > 0) { if (!FIsSpaceW(pwsz - 1)) break; pwsz--; cb -= sizeof(*pwsz); } // NULL Term
*pwsz = L'\0'; } // Set String Size
if (pcb) *pcb = cb; // Done
return cb; }
// =============================================================================================
// Converts first two characters of lpcsz to a WORD
// =============================================================================================
SHORT ASCII_NFromSz (LPCSTR lpcsz) { char acWordStr[3]; Assert (lpcsz); CopyMemory (acWordStr, lpcsz, 2 * sizeof (char)); acWordStr[2] = '\0'; return ((SHORT) (StrToInt (acWordStr))); }
// =================================================================================
// Adjust the time at lpSysTime by adding the given lHoursToAdd &
// lMinutesToAdd. Returns the adjusted time at lpFileTime.
// =================================================================================
HRESULT HrAdjustTime (LPSYSTEMTIME lpSysTime, LONG lHoursToAdd, LONG lMinutesToAdd, LPFILETIME lpFileTime) { // Locals
HRESULT hr = S_OK; BOOL bResult = FALSE; LONG lUnitsToAdd = 0; LARGE_INTEGER liTime; LONGLONG liHoursToAdd = 1i64, liMinutesToAdd = 1i64;
// Check Params
AssertSz (lpSysTime && lpFileTime, "Null Parameter");
// Convert sys time to file time
if (!SystemTimeToFileTime (lpSysTime, lpFileTime)) { hr = TRAPHR (E_FAIL); DebugTrace( "SystemTimeToFileTime() failed, dwError=%d.\n", GetLastError()); goto Exit; }
// Init
liTime.LowPart = lpFileTime->dwLowDateTime; liTime.HighPart = lpFileTime->dwHighDateTime;
// Adjust the hour
if (lHoursToAdd != 0) { lUnitsToAdd = lHoursToAdd * 3600; liHoursToAdd *= lUnitsToAdd; liHoursToAdd *= 10000000i64; liTime.QuadPart += liHoursToAdd; }
// Adjust the minutes
if (lMinutesToAdd != 0) { lUnitsToAdd = lMinutesToAdd * 60; liMinutesToAdd *= lUnitsToAdd; liMinutesToAdd *= 10000000i64; liTime.QuadPart += liMinutesToAdd; }
// Assign the result to FILETIME
lpFileTime->dwLowDateTime = liTime.LowPart; lpFileTime->dwHighDateTime = liTime.HighPart;
Exit: return hr; }
// =================================================================================
// Addjust the time at lpSysTime according to the given Zone info,
// Returns the adjusted time at lpFileTime.
// =================================================================================
BOOL ProcessZoneInfo (LPSTR lpszZoneInfo, INT *lpcHoursToAdd, INT *lpcMinutesToAdd) { // Locals
ULONG cbZoneInfo; BOOL bResult;
// Init
*lpcHoursToAdd = 0; *lpcMinutesToAdd = 0; cbZoneInfo = lstrlen (lpszZoneInfo); bResult = TRUE;
// +hhmm or -hhmm
if ((*lpszZoneInfo == '-' || *lpszZoneInfo == '+') && cbZoneInfo <= 5) { // Take off
cbZoneInfo-=1;
// determine the hour/minute offset
if (cbZoneInfo == 4) { *lpcMinutesToAdd = (INT)StrToInt (lpszZoneInfo+3); *(lpszZoneInfo+3) = 0x00; *lpcHoursToAdd = (INT)StrToInt(lpszZoneInfo+1); }
// 3
else if (cbZoneInfo == 3) { *lpcMinutesToAdd = (INT)StrToInt (lpszZoneInfo+2); *(lpszZoneInfo+2) = 0x00; *lpcHoursToAdd = (INT)StrToInt (lpszZoneInfo+1); }
// 2
else if (cbZoneInfo == 2 || cbZoneInfo == 1) { *lpcMinutesToAdd = 0; *lpcHoursToAdd = (INT)StrToInt(lpszZoneInfo+1); } if (*lpszZoneInfo == '+') { *lpcHoursToAdd = -*lpcHoursToAdd; *lpcMinutesToAdd = -*lpcMinutesToAdd; } }
// Xenix conversion: TZ = current time zone or other unknown tz types.
else if (lstrcmpi (lpszZoneInfo, "TZ") == 0 || lstrcmpi (lpszZoneInfo, "LOCAL") == 0 || lstrcmpi (lpszZoneInfo, "UNDEFINED") == 0) { TIME_ZONE_INFORMATION tzi ; DWORD dwRet = GetTimeZoneInformation (&tzi); if (dwRet != 0xFFFFFFFF) { LONG cMinuteBias = tzi.Bias;
if (dwRet == TIME_ZONE_ID_STANDARD) cMinuteBias += tzi.StandardBias ;
else if (dwRet == TIME_ZONE_ID_DAYLIGHT) cMinuteBias += tzi.DaylightBias ;
*lpcHoursToAdd = cMinuteBias / 60 ; *lpcMinutesToAdd = cMinuteBias % 60 ; } else { AssertSz (FALSE, "Why would this happen"); bResult = FALSE; } }
// Loop through known time zone standards
else { for (INT i=0; g_rgZones[i].lpszZoneCode!=NULL; i++) { if (lstrcmpi (lpszZoneInfo, g_rgZones[i].lpszZoneCode) == 0) { *lpcHoursToAdd = g_rgZones[i].cHourOffset; *lpcMinutesToAdd = g_rgZones[i].cMinuteOffset; break; } }
if (g_rgZones[i].lpszZoneCode == NULL) { DebugTrace( "Unrecognized zone info: [%s]\n", lpszZoneInfo ); bResult = FALSE; } }
return bResult; }
#define IS_DIGITA(ch) (ch >= '0' && ch <= '9')
#define IS_DIGITW(ch) (ch >= L'0' && ch <= L'9')
// ---------------------------------------------------------------------------------------
// StrToUintA
// ---------------------------------------------------------------------------------------
OESTDAPI_(UINT) StrToUintA(LPCSTR lpSrc) { UINT n = 0;
Assert(*lpSrc != '-');
while (IS_DIGITA(*lpSrc)) { n *= 10; n += *lpSrc - '0'; lpSrc++; } return n; }
// ---------------------------------------------------------------------------------------
// StrToUintW
// ---------------------------------------------------------------------------------------
OESTDAPI_(UINT) StrToUintW(LPCWSTR lpSrc) { UINT n = 0;
Assert(*lpSrc != '-');
while (IS_DIGITW(*lpSrc)) { n *= 10; n += *lpSrc - L'0'; lpSrc++; } return n; }
// ---------------------------------------------------------------------------------------
// FIsValidFileNameCharW
// ---------------------------------------------------------------------------------------
OESTDAPI_(BOOL) FIsValidFileNameCharW(WCHAR wch) { // Locals
LPWSTR pwsz; static const WCHAR s_pwszBad[] = L"<>:\"/\\|?*";
pwsz = (LPWSTR)s_pwszBad; while(*pwsz) { if (wch == *pwsz) return FALSE; pwsz++; }
// Shouldn't allow any control chars
if ((wch >= 0x0000) && (wch < 0x0020)) return FALSE;
// Done
return TRUE; }
// --------------------------------------------------------------------------
// FIsValidFileNameCharA
// --------------------------------------------------------------------------
OESTDAPI_(BOOL) FIsValidFileNameCharA(UINT codepage, CHAR ch) { // Locals
LPSTR psz; static const CHAR s_szBad[] = "<>:\"/\\|?*";
psz = (LPSTR)s_szBad; while(*psz) { if (IsDBCSLeadByteEx(codepage, *psz)) psz++; else if (ch == *psz) return FALSE; psz++; }
// Shouldn't allow any control chars
if ((ch >= 0x00) && (ch < 0x20)) return FALSE;
// Done
return TRUE; }
// --------------------------------------------------------------------------
// CleanupFileNameInPlaceA
// --------------------------------------------------------------------------
OESTDAPI_(ULONG) EXPORT_16 CleanupFileNameInPlaceA(UINT codepage, LPSTR psz) { UINT ich=0; UINT cch=lstrlen(psz);
// Fixup codepage?
if (1200 == codepage) codepage = CP_ACP;
// Loop and remove invalid chars
while (ich < cch) { // If lead byte, skip it, its leagal
if (IsDBCSLeadByteEx(codepage, psz[ich])) ich+=2;
// Illeagl file name character ?
else if (!FIsValidFileNameCharA(codepage, psz[ich])) { MoveMemory (psz + ich, psz + (ich + 1), cch - ich); cch--; } else ich++; }
// Return the Length
return cch; }
// --------------------------------------------------------------------------
// CleanupFileNameInPlaceW
// --------------------------------------------------------------------------
OESTDAPI_(ULONG) EXPORT_16 CleanupFileNameInPlaceW(LPWSTR pwsz) { // Locals
ULONG ich=0; ULONG cch=lstrlenW(pwsz);
// Loop and remove invalids
while (ich < cch) { // Illeagl file name character ?
if (!FIsValidFileNameCharW(pwsz[ich])) pwsz[ich]=L'_'; ich++; }
// Return the length
return cch; }
// =============================================================================================
// ReplaceChars
// =============================================================================================
OESTDAPI_(INT) EXPORT_16 ReplaceChars(LPCSTR pszString, CHAR chFind, CHAR chReplace) { // Locals
LPSTR pszT=(LPSTR)pszString; DWORD nCount=0;
// Loop for ch in pszString
while(*pszT) { // Lead Byte
if (IsDBCSLeadByte(*pszT)) pszT++; else if (*pszT == chFind) { *pszT = chReplace; nCount++; } pszT++; }
// Not Found
return nCount; }
OESTDAPI_(INT) EXPORT_16 ReplaceCharsW(LPCWSTR pszString, WCHAR chFind, WCHAR chReplace) { // Locals
LPWSTR pszT = (LPWSTR)pszString; DWORD nCount=0;
// Loop for ch in pszString
while(*pszT) { if (*pszT == chFind) { *pszT = chReplace; nCount++; } pszT++; }
// Not Found
return nCount; }
OESTDAPI_(BOOL) IsValidFileIfFileUrl(LPSTR pszUrl) { TCHAR rgch[MAX_PATH]; ULONG cch=ARRAYSIZE(rgch);
// pathCreate from url execpts a cannonicalised url with file:// infront
if (UrlCanonicalizeA(pszUrl, rgch, &cch, 0)==S_OK) { cch = ARRAYSIZE(rgch); if (PathCreateFromUrlA(rgch, rgch, &cch, 0)==S_OK && !PathFileExistsA(rgch)) return FALSE; }
return TRUE;
}
OESTDAPI_(BOOL) IsValidFileIfFileUrlW(LPWSTR pwszUrl) { WCHAR wsz[MAX_PATH]; ULONG cch=ARRAYSIZE(wsz);
// pathCreate from url execpts a cannonicalised url with file:// infront
if (UrlCanonicalizeW(pwszUrl, wsz, &cch, 0)==S_OK) { cch = ARRAYSIZE(wsz); if (PathCreateFromUrlW(wsz, wsz, &cch, 0)==S_OK && !PathFileExistsW(wsz)) return FALSE; }
return TRUE;
}
/***
*char *StrTokEx(pstring, control) - tokenize string with delimiter in control * *Purpose: * StrTokEx considers the string to consist of a sequence of zero or more * text tokens separated by spans of one or more control chars. the first * call, with string specified, returns a pointer to the first char of the * first token, and will write a null char into pstring immediately * following the returned token. when no tokens remain * in pstring a NULL pointer is returned. remember the control chars with a * bit map, one bit per ascii char. the null char is always a control char. * *Entry: * char **pstring - ptr to ptr to string to tokenize * char *control - string of characters to use as delimiters * *Exit: * returns pointer to first token in string, * returns NULL when no more tokens remain. * pstring points to the beginning of the next token. * *WARNING!!! * upon exit, the first delimiter in the input string will be replaced with '\0' * *******************************************************************************/ char * __cdecl StrTokEx (char ** ppszIn, const char * pcszCtrlIn) { unsigned char *psz; const unsigned char *pszCtrl = (const unsigned char *)pcszCtrlIn; unsigned char map[32] = {0}; LPSTR pszToken; if(*ppszIn == NULL) return NULL; /* Set bits in delimiter table */ do { map[*pszCtrl >> 3] |= (1 << (*pszCtrl & 7)); } while (*pszCtrl++); /* Initialize str. */ psz = (unsigned char*)*ppszIn; /* Find beginning of token (skip over leading delimiters). Note that
* there is no token if this loop sets str to point to the terminal * null (*str == '\0') */ while ((map[*psz >> 3] & (1 << (*psz & 7))) && *psz) psz++; pszToken = (LPSTR)psz; /* Find the end of the token. If it is not the end of the string,
* put a null there. */ for (; *psz ; psz++) { if (map[*psz >> 3] & (1 << (*psz & 7))) { *psz++ = '\0'; break; } } /* string now points to beginning of next token */ *ppszIn = (LPSTR)psz; /* Determine if a token has been found. */ if (pszToken == (LPSTR)psz) return NULL; else return pszToken; }
|