|
|
#include "priv.h"
#pragma hdrstop
#include "limits.h"
/*********** STRINGS - Should _not_ be localized */ #define SZOFCROOT TEXT("Software\\Microsoft\\Microsoft Office\\95\\")
#define SZOFCSHAREDROOT TEXT("Software\\Microsoft\\Shared Tools\\")
const TCHAR vcszCreateShortcuts[] = SZOFCROOT TEXT("Shell Folders"); const TCHAR vcszKeyAnthem[] = SZOFCROOT TEXT("Anthem"); const TCHAR vcszKeyFileNewNFT[] = SZOFCROOT TEXT("FileNew\\NFT"); const TCHAR vcszKeyFileNewLocal[] = SZOFCROOT TEXT("FileNew\\LocalTemplates"); const TCHAR vcszKeyFileNewShared[] = SZOFCROOT TEXT("FileNew\\SharedTemplates"); const TCHAR vcszKeyFileNew[] = SZOFCROOT TEXT("FileNew"); const TCHAR vcszFullKeyFileNew[] = TEXT("HKEY_CURRENT_USER\\") SZOFCROOT TEXT("FileNew"); const TCHAR vcszKeyIS[] = SZOFCROOT TEXT("IntelliSearch"); const TCHAR vcszSubKeyISToWHelp[] = TEXT("towinhelp"); const TCHAR vcszSubKeyAutoInitial[] = TEXT("CorrectTwoInitialCapitals"); const TCHAR vcszSubKeyAutoCapital[] = TEXT("CapitalizeNamesOfDays"); const TCHAR vcszSubKeyReplace[] = TEXT("ReplaceText"); const TCHAR vcszIntlPrefix[] = TEXT("MSO5"); const TCHAR vcszDllPostfix[] = TEXT(".DLL"); const TCHAR vcszName[] = TEXT("Name"); const TCHAR vcszType[] = TEXT("Type"); const TCHAR vcszApp[] = TEXT("Application"); const TCHAR vcszCmd[] = TEXT("Command"); const TCHAR vcszTopic[] = TEXT("Topic"); const TCHAR vcszDde[] = TEXT("DDEExec"); const TCHAR vcszRc[] = TEXT("ReturnCode"); const TCHAR vcszPos[] = TEXT("Position"); const TCHAR vcszPrevue[] = TEXT("Preview"); const TCHAR vcszFlags[] = TEXT("Flags"); const TCHAR vcszNFT[] = TEXT("NFT"); const TCHAR vcszMicrosoft[] = TEXT("Microsoft"); const TCHAR vcszElipsis[] = TEXT(" ..."); const TCHAR vcszLocalPath[] = TEXT("C:\\Microsoft Office\\Templates"); const TCHAR vcszAllFiles[] = TEXT("*.*\0\0"); const TCHAR vcszSpace[] = TEXT(" "); const TCHAR vcszMSNInstalled[] = TEXT("SOFTWARE\\Microsoft\\MOS\\SoftwareInstalled"); const TCHAR vcszMSNDir[] = SZOFCROOT TEXT("Microsoft Network"); const TCHAR vcszMSNLocDir[] = TEXT("Local Directory"); const TCHAR vcszMSNNetDir[] = TEXT("Network Directory"); const TCHAR vcszMSNFiles[] = TEXT("*.mcc\0\0"); const TCHAR vcszShellFolders[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"); const TCHAR vcszUserShellFolders[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"); const TCHAR vcszDefaultShellFolders[] = TEXT(".Default\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"); const TCHAR vcszDefaultUserShellFolders[] = TEXT(".Default\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"); const TCHAR vcszMyDocs[] = TEXT("Personal"); const TCHAR vcszNoTracking[] = SZOFCROOT TEXT("Options\\NoTracking"); const TCHAR vcszOldDocs[] = SZOFCROOT TEXT("Old Doc"); #ifdef WAIT3340
const TCHAR vcszMSHelp[]= TEXT("SOFTWARE\\Microsoft\\Windows\\Help"); #endif
BOOL fChicago = TRUE; // Are we running on Chicago or what!!
/*--------------------------------------------------------------------
* offglue.c Util routines taken from office.c --------------------------------------------------------------------*/
VOID ULIntDivide(ULInt FAR *, USHORT); VOID AddSzRes(TCHAR *, TCHAR *); /*-----------------------------------------------------------------------
| PAlloc | Simple little routine that allocs memory in case the client did not provide its function. | | Arguments: | cb: number of bytes | | Returns: | NULL if fails to alloc else the pointer | -----------------------------------------------------------------------*/ #define DEF_ALLOC_FLAGS (0x00000800)
void * (OFC_CALLBACK PAlloc)(unsigned cb) { void *pv; pv=(void *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY | DEF_ALLOC_FLAGS,cb); return(pv); } /*-----------------------------------------------------------------------
| FreeP | Simple little routine that frees memory in case the client did not provide its function | | Arguments: pv: ptr to be freed | cb: number of bytes | | Returns: | nothing -----------------------------------------------------------------------*/ void OFC_CALLBACK FreeP(void *pv, unsigned cb) { HeapFree(GetProcessHeap(),0,pv); } /*-----------------------------------------------------------------------
| PvMemAlloc | Simple little routine that allocs memory | | Arguments: | cb: number of bytes | | Returns: | NULL if fails to alloc else the pointer | -----------------------------------------------------------------------*/ void *PvMemAlloc(DWORD cb) { void *pv;
pv = PAlloc((unsigned)cb); return(pv); } /*-----------------------------------------------------------------------
| PvMemRealloc | Simple little routine that reallocates memory | | Arguments: | cb: number of bytes | | Returns: | NULL if fails to alloc else the pointer | -----------------------------------------------------------------------*/ void *PvMemRealloc(void *pmem, DWORD cbOld, DWORD cbNew) { void *pv; pv = PvMemAlloc(cbNew);
if (pv!=NULL && pmem) { PbMemCopy(pv, pmem, cbOld); VFreeMemP(pmem, cbOld); } return(pv); } void *PvStrDup(LPCTSTR psz) { TCHAR *pszNew;
if ((pszNew = PvMemAlloc((CchTszLen(psz)+1)*sizeof(TCHAR)))!=NULL) { SzCopy(pszNew, (void *)psz); } return pszNew; } /*-----------------------------------------------------------------------
| VFreeMemP | Simple little routine that frees memory | | Arguments: | pv: ptr to be freed | cb: number of bytes | | Returns: | nothing -----------------------------------------------------------------------*/ void VFreeMemP(void *pv, DWORD cb) { FreeP(pv,cb); } //
// FUNCTION: FScanMem
//
// Purpose: To scan memory for a given value.
//
// Parameters: pb - pointer to memory
// bVal - value to scan for
// cb - cb pointed to by pb
//
// Returns: TRUE iff all the memory has the value cbVal.
// FALSE otherwise.
//
BOOL FScanMem(LPBYTE pb, byte bVal, DWORD cb) { DWORD i; for (i = 0; i < cb; ++i) { if (*pb++ != bVal) return FALSE; } return TRUE; }
int CchGetString(ids,rgch,cchMax) int ids; TCHAR rgch[]; int cchMax; { return(LoadString(g_hmodThisDll, ids, rgch, cchMax)); }
// Convert a number in units of 100ns into number of minutes.
//
// Parameters:
//
// lptime - on input: contains a number expressed in 100ns.
// on output: contains the equivalent number of minutes.
//
// Return value:
//
// None.
//
VOID Convert100nsToMin(LPFILETIME lpTime) { ULInt ul;
ul.dw = lpTime->dwLowDateTime; ul.dwh = lpTime->dwHighDateTime; ULIntDivide(&ul, 1000); // These two calls converts to
ULIntDivide(&ul, 10000); // seconds
ULIntDivide(&ul, 60); // Convert to minutes
lpTime->dwLowDateTime = ul.dw; lpTime->dwHighDateTime = ul.dwh; }
//
// Function: ULIntDivide
//
// Purpose: To divide a ULInt with a USHORT and
// stick the result in the 1st param
//
VOID ULIntDivide(ULInt FAR *lpULInt, USHORT div) { ULInt ulOut, ulIn, r;
ulIn = *lpULInt;
ulOut.w3 = ulIn.w3/div; r.w3 = ulIn.w3%div;
ulOut.w2 = (ulIn.w2 + r.w3*65536)/div; r.w2 = (ulIn.w2 + r.w3*65536)%div;
ulOut.w1 = (ulIn.w1 + r.w2*65536)/div; r.w1 = (ulIn.w1 + r.w2*65536)%div;
ulOut.w0 = (ulIn.w0 + r.w1*65536)/div; r.w0 = (ulIn.w0 + r.w1*65536)%div;
*lpULInt = ulOut; }
#define SZRES_BUFMAX 100
//
// Function: ULIntToSz
//
// Purpose: Converts a ULInt to an sz without leading zero's
//
WORD CchULIntToSz(ULInt ulint, TCHAR *psz, WORD cbMax) { TCHAR szRes[SZRES_BUFMAX]; TCHAR szT[SZRES_BUFMAX]; BYTE b,i;
if ((ulint.dw == 0) && (ulint.dwh == 0)) { *psz++ = TEXT('0'); *psz = 0; return(1); // Don't include zero-terminator
} for (i = 0; i < SZRES_BUFMAX; ++i) szRes[i] = szT[i] = 0;
i = sizeof(ULInt)*8; // the number of bits
while (i--) { if (i != sizeof(ULInt)*8 - 1) // no need to add 1st time
AddSzRes(szRes,szRes); // through, sz is all 0's
if (ulint.dwh & 0x80000000) { szT[SZRES_BUFMAX-2] = 1; // Leave the last element for
AddSzRes(szRes, szT); // zero-terminator
}
b = (ulint.dw & 0x80000000) ? 1 : 0; ulint.dw <<= 1; ulint.dwh <<= 1;
ulint.dwh |= b; }
for (i = 0; i <= SZRES_BUFMAX-2; ++i) szRes[i] = szRes[i] + TEXT('0'); szRes[SZRES_BUFMAX-1] = 0;
i = 0; // Strip off leading zero's
while (szRes[i] == TEXT('0')) ++i;
#ifdef DEBUG
if (SZRES_BUFMAX - i > cbMax) Assert(FALSE); #endif
for (b = i; b < SZRES_BUFMAX; ++b) *psz++ = szRes[b];
return(SZRES_BUFMAX - i -1); // Don't include zero-terminator
}
VOID AddSzRes(pszRes, pszT) TCHAR *pszRes; TCHAR *pszT; { int i; BOOL fCarry;
i = SZRES_BUFMAX-2; // Leave room for zero-terminator
fCarry = FALSE;
while (i) { pszRes[i] = pszRes[i] + pszT[i] + fCarry; if (pszRes[i] > 9) { fCarry = TRUE; pszRes[i] = pszRes[i] - 10; } else fCarry = FALSE; --i; } }
/* CchTszLen
* * Returns the length of a null-termianted string. * * Arguments: * sz - string to take the length of * * Returns: * length of sz * */ int CchTszLen(const TCHAR *psz) { CONST TCHAR *pch;
Assert(psz!=NULL); pch = psz; while (*pch++) ; return (int)(pch - psz - 1); }
int CchWszLen(const WCHAR *psz) { CONST WCHAR *pch;
Assert(psz!=NULL); pch = psz; while (*pch++) ; return (int)(pch - psz - 1); }
/* CchAnsiSzLen
* * Returns the length of a null-termianted ANSI string. * * Arguments: * sz - string to take the length of * * Returns: * length of sz * */ int CchAnsiSzLen(const CHAR *psz) { CONST CHAR *pch;
Assert(psz!=NULL); pch = psz; while (*pch++) ; return (int)(pch - psz - 1); }
/* FillBuf
* * Fills the given buffer with given byte value. * * Arguments: * ptr to buf, byte value to be filled and the size of the buf * * Returns: * nothing * */ VOID FillBuf(void *p, unsigned w, unsigned cb) { while (cb--) *((BYTE *)p)++ = (BYTE)w; } /* PbMemCopy
* * Copies the given no. of bytes of the given src buffer to the given dst. * * Arguments: * ptr to Dst, ptr to Src, no. of bytes to cp * * Returns: * advanced pbDst * */ BYTE *PbMemCopy(void *pvDst, const void *pvSrc, unsigned cb) { #define pbSrc ((BYTE *)pvSrc)
#define pbDst ((BYTE *)pvDst)
DWORD cbSav;
Assert((signed)cb >=0 ); /* BUG!! Need better blts */ if (pbDst < pbSrc) { while (cb--) *pbDst++ = *pbSrc++; return pbDst; } pbDst += (cb-1); pbSrc += (cb-1); cbSav = cb; while (cb--) *pbDst-- = *pbSrc--; return pbDst+cbSav+1; #undef pbDst
#undef pbSrc
} /* SzCopy
* * Copies the given src sz to the given the given dst. * * Arguments: * ptr to Dst, ptr to Src * * Returns: * nothing * */ VOID SzCopy(void *pvDst, const void *pvSrc) { PbMemCopy(pvDst, pvSrc, (CchTszLen(pvSrc)+1)*sizeof(TCHAR)); } /* PbSzNCopy
* * Copies the given src sz to the given the given dst. * Only Min of (cch, len of Src) is copied * Arguments: * ptr to Dst, ptr to Src and the cb * * Returns: * advanced pvSrc * */ BYTE *PbSzNCopy(void *pvDst, const void *pvSrc, unsigned cch) { DWORD cchSrc; BYTE *pb; cchSrc=CchTszLen(pvSrc); if(cch <= cchSrc) pb = PbMemCopy(pvDst, pvSrc, cch*sizeof(TCHAR)); else { pb = PbMemCopy(pvDst, pvSrc, cchSrc*sizeof(TCHAR)); FillBuf(pb, 0, (cch-cchSrc)*sizeof(TCHAR)); pb += (cch-cchSrc); } return(pb); }
/*==========================================================================
C Runtime call replacements
FUTURE: This must be (extensivly) DBCS enabled.
================================================================== MIKEL =*/
int errno;
int isspace(int c) { return (c >= 0x09 && c <= 0x0D) || c == 0x20 || c == 0x200F /*unicode RTL*/|| c == 0x200E /*unicode LTR*/ ; }
int __isascii(int c) { return !(c & 0x80); }
int getdigit(const TCHAR *pch) { if ((TEXT('0') <= *pch) && (*pch <= TEXT('9'))) return *pch - TEXT('0');
if ((TEXT('a') <= *pch) && (*pch <= TEXT('z'))) return *pch - TEXT('a') + 10;
if ((TEXT('A') <= *pch) && (*pch <= TEXT('Z'))) return *pch - TEXT('A') + 10;
return -1; }
long strtol(const TCHAR *pch, TCHAR **ppch, int iBase) { /* simple regular expression parsing for
* [white] [sign] [0] [{x | X}] [digits] */ unsigned long ulNum = 0; int iNeg = 0; int iInvalid = 1; int iDigit = 0;
#ifdef DEBUG
if (iBase) Assert((iBase > 1) && (iBase < 37)); #endif
while (isspace(*pch)) pch++;
if (*pch == TEXT('-')) { pch++; iNeg = 1; } else if (*pch == TEXT('+')) pch++;
if (*pch == TEXT('0')) { pch++;
/* Hex or Octal */ if (isalnum(*pch) && (iBase == 0)) { if ((*pch == TEXT('x') || *pch == TEXT('X'))) { iBase = 16; pch++; } else { iBase = 8; } } else iInvalid = 0; }
/* Decimal */ if (iBase == 0) iBase = 10;
while ((iDigit = getdigit(pch)) != -1) { if ((iDigit < 0) || (iDigit >= iBase)) goto Invalid;
iInvalid = 0; // only needs doing first time!
// BUG FIX for RAID #969 - not curerntly handling overflow
// If we are going to add a digit, before doing so make sure
// that the current number is no greater than the max it could
// be. We add one in because integer divide truncates, and
// we might be right around LONG_MAX.
if (ulNum > (unsigned)((LONG_MAX / iBase) + 1)) { errno = ERANGE; return iNeg ? LONG_MIN : LONG_MAX; }
ulNum = ulNum * iBase + (unsigned int)iDigit;
// BUG FIX cont'd: Now, since ulNum can be no bigger
// than (LONG_MAX / iBase) + 1, then this multiplication
// can result in something no bigger than LONG_MAX + iBase,
// and ulNum is limited by LONG_MAX + iBase + iDigit. This
// will set the high bit of this LONG in the worst case, and
// since iBase + iDigit is much less than LONG_MAX, will not
// underflow us undetectably.
if (ulNum > (ULONG)LONG_MAX) { errno = ERANGE; return iNeg ? LONG_MIN : LONG_MAX; } pch++; }
if (iInvalid) { Invalid: errno = ERANGE; return 0; }
if (ppch) *ppch = (TCHAR *)pch;
Assert(ulNum <= LONG_MAX); return iNeg ? - ((long)ulNum) : (long)ulNum; }
int ScanDateNums(TCHAR *pch, TCHAR *pszSep, unsigned int aiNum[], int cNum, int iYear) { int i = 0; TCHAR *pSep;
if (cNum < 1) return 1;
do { if ((aiNum[i] = strtol(pch, &pch, 10)) == 0 ) if( i != iYear ) return 0; i++ ;
if (i < cNum) { while (isspace(*pch)) pch++;
/* check the separator */ pSep = pszSep; while (*pSep && (*pSep == *pch)) pSep++, pch++;
if (*pSep && (*pSep != *pch)) return 0; } } while (*pch && (i < cNum));
return 1; }
//
// Converts a filetime into a number of minutes. It is assumed that
// the filetime contains the number of minutes in units of 100ns
//
// cbMax - size of psz
// fMinutes - should we tag on the string Minute(s) at the end?
//
VOID PASCAL VFtToSz(LPFILETIME lpft, LPTSTR psz, WORD cchMax, BOOL fMinutes) { ULInt ulint; FILETIME ft; WORD cch; int ids;
if (lpft != NULL) { ft = *lpft; Convert100nsToMin(&ft);
ulint.dw = ft.dwLowDateTime;; ulint.dwh = ft.dwHighDateTime;;
cch = CchULIntToSz(ulint, psz, (WORD)(fMinutes ? (cchMax-1) : // not including zero terminator
cchMax)); if (!fMinutes) return;
ids = (cch == 1 && *psz == TEXT('1')) ? idsMinute : idsMinutes; psz[cch] = TEXT(' '); CchGetString(ids, psz+cch+1, cchMax-cch-1); } else *psz = 0; }
//
// Displays the actual alert
//
static int DoMessageBox(HWND hwnd, TCHAR *pszText, TCHAR *pszTitle, UINT fuStyle) { int res; res = MessageBox((hwnd == NULL) ? GetFocus() : hwnd, pszText, pszTitle, fuStyle); return(res); } //--------------------------------------------------------------------------
// Displays the give ids as an alert
//--------------------------------------------------------------------------
int IdDoAlert(HWND hwnd, int ids, int mb) { TCHAR rgch[258]; TCHAR rgchM[258];
CchGetString(ids, rgch, 258); CchGetString(idsMsftOffice, rgchM, 258); return(DoMessageBox (hwnd, rgch, rgchM, mb)); }
/*====================================================================
============================================================= MikeL */
int _cdecl _purecall(void) { #ifdef DEBUG
Assert(fFalse); #endif
return 0; }
// Wide-Char - MBCS helpers
LPWSTR WINAPI A2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars) { //_ASSERTE(lpa != NULL);
//_ASSERTE(lpw != NULL);
// verify that no illegal character present
// since lpw was allocated based on the size of lpa
// don't worry about the number of chars
lpw[0] = '\0'; MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars); return lpw; } LPSTR WINAPI W2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars) { //_ASSERTE(lpw != NULL);
//_ASSERTE(lpa != NULL);
// verify that no illegal character present
// since lpa was allocated based on the size of lpw
// don't worry about the number of chars
lpa[0] = '\0'; WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL); return lpa; }
|