Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

557 lines
15 KiB

/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
//
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
////
// intl.c - internationalization functions
////
#include "winlocal.h"
#include <stdlib.h>
#include "intl.h"
#include "mem.h"
#include "str.h"
#include "trace.h"
////
// private definitions
////
// intl control struct
//
typedef struct INTL
{
DWORD dwVersion;
HINSTANCE hInst;
HTASK hTask;
TCHAR szShortDate[32];
TCHAR szDateSep[32];
TCHAR szTimeSep[32];
TCHAR szAMPMSep[32];
TCHAR szAM[32];
TCHAR szPM[32];
int iDate;
int iTime;
int iTLZero;
BOOL fYearCentury;
BOOL fMonthLeadingZero;
BOOL fDayLeadingZero;
BOOL fHourLeadingZero;
BOOL fMinuteLeadingZero;
BOOL fSecondLeadingZero;
int iLZero;
TCHAR szDecimal[32];
} INTL, FAR *LPINTL;
// helper functions
//
static LPINTL IntlGetPtr(HINTL hIntl);
static HINTL IntlGetHandle(LPINTL lpIntl);
////
// public functions
////
// IntlInit - initialize intl engine
// <dwVersion> (i) must be INTL_VERSION
// <hInst> (i) instance handle of calling module
// return handle (NULL if error)
//
HINTL DLLEXPORT WINAPI IntlInit(DWORD dwVersion, HINSTANCE hInst)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl = NULL;
if (dwVersion != INTL_VERSION)
fSuccess = TraceFALSE(NULL);
else if (hInst == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpIntl = (LPINTL) MemAlloc(NULL, sizeof(INTL), 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else
{
lpIntl->dwVersion = dwVersion;
lpIntl->hInst = hInst;
lpIntl->hTask = GetCurrentTask();
GetProfileString(TEXT("intl"), TEXT("sShortDate"), TEXT("M/d/yy"), lpIntl->szShortDate, SIZEOFARRAY(lpIntl->szShortDate));
GetProfileString(TEXT("intl"), TEXT("sDate"), TEXT("/"), lpIntl->szDateSep, SIZEOFARRAY(lpIntl->szDateSep));
GetProfileString(TEXT("intl"), TEXT("sTime"), TEXT(":"), lpIntl->szTimeSep, SIZEOFARRAY(lpIntl->szTimeSep));
StrCpy(lpIntl->szAMPMSep, TEXT(" "));
GetProfileString(TEXT("intl"), TEXT("s1159"), TEXT("AM"), lpIntl->szAM, SIZEOFARRAY(lpIntl->szAM));
GetProfileString(TEXT("intl"), TEXT("s2359"), TEXT("PM"), lpIntl->szPM, SIZEOFARRAY(lpIntl->szPM));
lpIntl->iDate = GetProfileInt(TEXT("intl"), TEXT("iDate"), 0);
lpIntl->iTime = GetProfileInt(TEXT("intl"), TEXT("iTime"), 0);
lpIntl->iTLZero = GetProfileInt(TEXT("intl"), TEXT("iTLZero"), 0);
lpIntl->fYearCentury = (BOOL) (StrStr(lpIntl->szShortDate, TEXT("yyyy")) != NULL);
lpIntl->fMonthLeadingZero = (BOOL) (StrStr(lpIntl->szShortDate, TEXT("MM")) != NULL);
lpIntl->fDayLeadingZero = (BOOL) (StrStr(lpIntl->szShortDate, TEXT("dd")) != NULL);
lpIntl->fHourLeadingZero = (BOOL) (lpIntl->iTLZero != 0);
lpIntl->fMinuteLeadingZero = TRUE;
lpIntl->fSecondLeadingZero = TRUE;
lpIntl->iLZero = GetProfileInt(TEXT("intl"), TEXT("iLZero"), 0);
GetProfileString(TEXT("intl"), TEXT("sDecimal"), TEXT("."), lpIntl->szDecimal, SIZEOFARRAY(lpIntl->szDecimal));
}
if (!fSuccess)
{
IntlTerm(IntlGetHandle(lpIntl));
lpIntl = NULL;
}
return fSuccess ? IntlGetHandle(lpIntl) : NULL;
}
// IntlTerm - shut down intl engine
// <hIntl> (i) handle returned from IntlInit
// return 0 if success
//
int DLLEXPORT WINAPI IntlTerm(HINTL hIntl)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl;
if ((lpIntl = IntlGetPtr(hIntl)) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpIntl = MemFree(NULL, lpIntl)) != NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? 0 : -1;
}
// IntlDateGetText - construct date text based on <y>, <m>, <d>
// <hIntl> (i) handle returned from IntlInit
// <y> (i) year
// <m> (i) month
// <d> (i) day
// <lpszText> (o) buffer to copy date text
// <sizText> (i) size of buffer
// <dwFlags> (i) option flags
// INTL_NOYEAR do not include year in text output
// return 0 if success
//
int DLLEXPORT WINAPI IntlDateGetText(HINTL hIntl, int y, int m, int d, LPTSTR lpszText, size_t sizText, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl;
if ((lpIntl = IntlGetPtr(hIntl)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpszText != NULL)
{
TCHAR szYear[16];
TCHAR szMonth[16];
TCHAR szDay[16];
TCHAR szText[64];
*szYear = '\0';
if (!lpIntl->fYearCentury)
y %= 100;
if (y < 10)
StrCat(szYear, TEXT("0"));
StrItoA(y, StrChr(szYear, '\0'), 10);
*szMonth = '\0';
if (lpIntl->fMonthLeadingZero && m < 10)
StrCat(szMonth, TEXT("0"));
StrItoA(m, StrChr(szMonth, '\0'), 10);
*szDay = '\0';
if (lpIntl->fDayLeadingZero && d < 10)
StrCat(szDay, TEXT("0"));
StrItoA(d, StrChr(szDay, '\0'), 10);
*szText = '\0';
if (lpIntl->iDate == IDATE_MDY)
{
StrCat(szText, szMonth);
StrCat(szText, lpIntl->szDateSep);
StrCat(szText, szDay);
if (!(dwFlags & INTL_NOYEAR))
{
StrCat(szText, lpIntl->szDateSep);
StrCat(szText, szYear);
}
}
else if (lpIntl->iDate == IDATE_DMY)
{
StrCat(szText, szDay);
StrCat(szText, lpIntl->szDateSep);
StrCat(szText, szMonth);
if (!(dwFlags & INTL_NOYEAR))
{
StrCat(szText, lpIntl->szDateSep);
StrCat(szText, szYear);
}
}
else if (lpIntl->iDate == IDATE_YMD)
{
if (!(dwFlags & INTL_NOYEAR))
{
StrCat(szText, szYear);
StrCat(szText, lpIntl->szDateSep);
}
StrCat(szText, szMonth);
StrCat(szText, lpIntl->szDateSep);
StrCat(szText, szDay);
}
StrNCpy(lpszText, szText, sizText);
}
return fSuccess ? 0 : -1;
}
// IntlTimeGetText - construct time text based on <h>, <m>, <s>
// <hIntl> (i) handle returned from IntlInit
// <h> (i) hour
// <m> (i) minute
// <s> (i) second
// <lpszText> (o) buffer to copy time text
// <sizText> (i) size of buffer
// <dwFlags> (i) option flags
// INTL_NOSECOND do not include second in text output
// INTL_NOAMPM do not include am or pm in text output
// INTL_NOAMPMSEPARATOR do not include space between time and am/pm
// return 0 if success
//
int DLLEXPORT WINAPI IntlTimeGetText(HINTL hIntl, int h, int m, int s, LPTSTR lpszText, size_t sizText, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl;
if ((lpIntl = IntlGetPtr(hIntl)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpszText != NULL)
{
TCHAR szHour[16];
TCHAR szMinute[16];
TCHAR szSecond[16];
BOOL fPM = FALSE;
TCHAR szText[64];
*szHour = '\0';
if (lpIntl->iTime == ITIME_12)
{
if (h > 11)
fPM = TRUE;
if (h > 12)
h -= 12;
if (h == 0)
h = 12;
}
if (lpIntl->fHourLeadingZero && h < 10)
StrCat(szHour, TEXT("0"));
StrItoA(h, StrChr(szHour, '\0'), 10);
*szMinute = '\0';
if (lpIntl->fMinuteLeadingZero && m < 10)
StrCat(szMinute, TEXT("0"));
StrItoA(m, StrChr(szMinute, '\0'), 10);
*szSecond = '\0';
if (lpIntl->fSecondLeadingZero && s < 10)
StrCat(szSecond, TEXT("0"));
StrItoA(s, StrChr(szSecond, '\0'), 10);
*szText = '\0';
StrCat(szText, szHour);
StrCat(szText, lpIntl->szTimeSep);
StrCat(szText, szMinute);
if (!(dwFlags & INTL_NOSECOND))
{
StrCat(szText, lpIntl->szTimeSep);
StrCat(szText, szSecond);
}
if (!(dwFlags & INTL_NOAMPM))
{
if (!(dwFlags & INTL_NOAMPMSEPARATOR))
StrCat(szText, lpIntl->szAMPMSep);
StrCat(szText, fPM ? lpIntl->szPM : lpIntl->szAM);
}
StrNCpy(lpszText, szText, sizText);
}
return fSuccess ? 0 : -1;
}
// IntlTimeSpanGetText - construct time span text based on <ms>
// <hIntl> (i) handle returned from IntlInit
// <ms> (i) milleseconds
// <nDecimalPlaces> (i) 0, 1, 2, or 3 decimal places for fraction
// <lpszText> (o) buffer to copy time span text
// <sizText> (i) size of buffer
// <dwFlags> (i) option flags
// INTL_HOURS_LZ include hours, even if zero
// INTL_MINUTES_LZ include minutes, even if zero
// INTL_SECONDS_LZ include seconds, even if zero
//
// NOTE: below are some examples
//
// dwFlags ms=7299650 ms=1234 ms=0
// --------------------------------------------------------
// 0 "2:01:39.650" "1.234" "0"
// INTL_HOURS_LZ "2:01:39.650" "0:00:01.234" "0:00:00.000"
// INTL_MINUTES_LZ "2:01:39.650" "0:01.234" "0:00.000"
// INTL_SECONDS_LZ "2:01:39.650" "1.234" "0.000"
//
// dwFlags ms=7299650 ms=1234 ms=0
// --------------------------------------------------------
// 3 "2:01:39.650" "1.234" ".000"
// 2 "2:01:39.65" "1.23" ".00"
// 1 "2:01:39.7" "1.2" ".0"
// 0 "2:01:39" "1" "0"
//
// return 0 if success
//
int DLLEXPORT WINAPI IntlTimeSpanGetText(HINTL hIntl, DWORD ms,
int nDecimalPlaces, LPTSTR lpszText, size_t sizText, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl;
if ((lpIntl = IntlGetPtr(hIntl)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpszText != NULL)
{
long h;
long m;
long s;
long f;
TCHAR szText[64];
// break ms into h, m, s, f
// NOTE: rounding must occur before we break ms
//
if (nDecimalPlaces == 1)
f = (long) ms + 50;
else if (nDecimalPlaces == 2)
f = (long) ms + 5;
else
f = (long) ms;
s = f / 1000;
f = f % 1000;
m = s / 60;
s = s % 60;
h = m / 60;
m = m % 60;
// construct text
//
*szText = '\0';
if (h > 0 || (dwFlags & INTL_HOURS_LZ))
{
if (lpIntl->fHourLeadingZero && h < 10)
StrCat(szText, TEXT("0"));
StrLtoA(h, StrChr(szText, '\0'), 10);
}
if (*szText != '\0' || m > 0 || (dwFlags & INTL_MINUTES_LZ))
{
if (*szText != '\0')
{
StrCat(szText, lpIntl->szTimeSep);
if (lpIntl->fMinuteLeadingZero && m < 10)
StrCat(szText, TEXT("0"));
}
StrLtoA(m, StrChr(szText, '\0'), 10);
}
if (*szText != '\0' || s > 0 || (dwFlags & INTL_SECONDS_LZ) ||
(ms == 0 && nDecimalPlaces == 0))
{
if (*szText != '\0')
{
StrCat(szText, lpIntl->szTimeSep);
if (lpIntl->fSecondLeadingZero && s < 10)
StrCat(szText, TEXT("0"));
}
StrLtoA(s, StrChr(szText, '\0'), 10);
}
switch (nDecimalPlaces)
{
case 3:
if (*szText != '\0' || ms < 1000)
{
StrCat(szText, lpIntl->szDecimal);
if (f < 100)
StrCat(szText, TEXT("0"));
if (f < 10)
StrCat(szText, TEXT("0"));
}
StrLtoA(f, StrChr(szText, '\0'), 10);
break;
case 2:
f = f / 10;
if (*szText != '\0' || ms < 1000)
{
StrCat(szText, lpIntl->szDecimal);
if (f < 10)
StrCat(szText, TEXT("0"));
}
StrLtoA(f, StrChr(szText, '\0'), 10);
break;
case 1:
f = f / 100;
if (*szText != '\0' || ms < 1000)
StrCat(szText, lpIntl->szDecimal);
StrLtoA(f, StrChr(szText, '\0'), 10);
break;
default:
break;
}
StrNCpy(lpszText, szText, sizText);
}
return fSuccess ? 0 : -1;
}
// IntlDateGetFormat - return current date format structure
// <hIntl> (i) handle returned from IntlInit
// <lpIntlDateFormat> (o) copy date format structure here
// return 0 if success
//
int DLLEXPORT WINAPI IntlDateGetFormat(HINTL hIntl, LPINTLDATEFORMAT lpIntlDateFormat)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl;
if ((lpIntl = IntlGetPtr(hIntl)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpIntlDateFormat != NULL)
{
MemSet(lpIntlDateFormat, 0,
sizeof(INTLDATEFORMAT));
MemCpy(lpIntlDateFormat->szShortDate, lpIntl->szShortDate,
sizeof(lpIntl->szShortDate));
MemCpy(lpIntlDateFormat->szDateSep, lpIntl->szDateSep,
sizeof(lpIntl->szDateSep));
lpIntlDateFormat->iDate = lpIntl->iDate;
lpIntlDateFormat->fYearCentury = lpIntl->fYearCentury;
lpIntlDateFormat->fMonthLeadingZero = lpIntl->fMonthLeadingZero;
lpIntlDateFormat->fDayLeadingZero = lpIntl->fDayLeadingZero;
}
return fSuccess ? 0 : -1;
}
// IntlTimeGetFormat - return current time format structure
// <hIntl> (i) handle returned from IntlInit
// <lpIntlTimeFormat> (o) copy time format structure here
// return 0 if success
//
int DLLEXPORT WINAPI IntlTimeGetFormat(HINTL hIntl, LPINTLTIMEFORMAT lpIntlTimeFormat)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl;
if ((lpIntl = IntlGetPtr(hIntl)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpIntlTimeFormat != NULL)
{
MemSet(lpIntlTimeFormat, 0,
sizeof(INTLDATEFORMAT));
MemCpy(lpIntlTimeFormat->szTimeSep, lpIntl->szTimeSep,
sizeof(lpIntl->szTimeSep));
MemCpy(lpIntlTimeFormat->szAMPMSep, lpIntl->szAMPMSep,
sizeof(lpIntl->szAMPMSep));
MemCpy(lpIntlTimeFormat->szAM, lpIntl->szAM,
sizeof(lpIntl->szAM));
MemCpy(lpIntlTimeFormat->szPM, lpIntl->szPM,
sizeof(lpIntl->szPM));
lpIntlTimeFormat->iTime = lpIntl->iTime;
lpIntlTimeFormat->fHourLeadingZero = lpIntl->fHourLeadingZero;
lpIntlTimeFormat->fMinuteLeadingZero = lpIntl->fMinuteLeadingZero;
lpIntlTimeFormat->fSecondLeadingZero = lpIntl->fSecondLeadingZero;
}
return fSuccess ? 0 : -1;
}
////
// helper functions
////
// IntlGetPtr - verify that intl handle is valid,
// <hIntl> (i) handle returned from IntlInit
// return corresponding intl pointer (NULL if error)
//
static LPINTL IntlGetPtr(HINTL hIntl)
{
BOOL fSuccess = TRUE;
LPINTL lpIntl;
if ((lpIntl = (LPINTL) hIntl) == NULL)
fSuccess = TraceFALSE(NULL);
else if (IsBadWritePtr(lpIntl, sizeof(INTL)))
fSuccess = TraceFALSE(NULL);
#ifdef CHECKTASK
// make sure current task owns the intl handle
//
else if (lpIntl->hTask != GetCurrentTask())
fSuccess = TraceFALSE(NULL);
#endif
return fSuccess ? lpIntl : NULL;
}
// IntlGetHandle - verify that intl pointer is valid,
// <lpIntl> (i) pointer to INTL struct
// return corresponding intl handle (NULL if error)
//
static HINTL IntlGetHandle(LPINTL lpIntl)
{
BOOL fSuccess = TRUE;
HINTL hIntl;
if ((hIntl = (HINTL) lpIntl) == NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? hIntl : NULL;
}