750 lines
18 KiB
C
750 lines
18 KiB
C
|
|
||
|
#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;
|
||
|
}
|