⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lang.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (cchCount1 < 0) cchCount1 = lstrlenW(lpString1);
    if (cchCount2 < 0) cchCount2 = lstrlenW(lpString2);

    String1.Length = String1.MaximumLength = cchCount1 * sizeof(WCHAR);
    String1.Buffer = (LPWSTR)lpString1;
    String2.Length = String2.MaximumLength = cchCount2 * sizeof(WCHAR);
    String2.Buffer = (LPWSTR)lpString2;


    if (dwCmpFlags & ~NORM_IGNORECASE)
    {
        DPRINT("CompareString: STUB flags - 0x%x\n", dwCmpFlags);
	Result = compare_unicode_string(&String1, &String2, dwCmpFlags);
    }
    else
        Result = RtlCompareUnicodeString(
                      &String1, &String2, dwCmpFlags & NORM_IGNORECASE);
    
    
    if (Result) /* need to translate result */
        return (Result < 0) ? CSTR_LESS_THAN : CSTR_GREATER_THAN;

    return CSTR_EQUAL;
}




/*
 * @implemented
 *
 * Get information about an aspect of a locale.
 *
 * PARAMS
 *  lcid   [I] LCID of the locale
 *  lctype [I] LCTYPE_ flags from "winnls.h"
 *  buffer [O] Destination for the information
 *  len    [I] Length of buffer in characters
 *
 * RETURNS
 *  Success: The size of the data requested. If buffer is non-NULL, it is filled
 *           with the information.
 *  Failure: 0. Use GetLastError() to determine the cause.
 *
 * NOTES
 *  - LOCALE_NEUTRAL is equal to LOCALE_SYSTEM_DEFAULT
 *  - The string returned is NUL terminated, except for LOCALE_FONTSIGNATURE,
 *    which is a bit string.
 */
INT STDCALL GetLocaleInfoA( LCID lcid, LCTYPE lctype, LPSTR buffer, INT len )
{
    WCHAR *bufferW;
    INT lenW, ret;

    if (len < 0 || (len && !buffer))
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return 0;
    }
    if (!len) buffer = NULL;

    if (!(lenW = GetLocaleInfoW( lcid, lctype, NULL, 0 ))) return 0;

    if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) )))
    {
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
        return 0;
    }
    if ((ret = GetLocaleInfoW( lcid, lctype, bufferW, lenW )))
    {
        if ((lctype & LOCALE_RETURN_NUMBER) ||
            ((lctype & ~LOCALE_LOCALEINFOFLAGSMASK) == LOCALE_FONTSIGNATURE))
        {
            /* it's not an ASCII string, just bytes */
            ret *= sizeof(WCHAR);
            if (buffer)
            {
                if (ret <= len) memcpy( buffer, bufferW, ret );
                else
                {
                    SetLastError( ERROR_INSUFFICIENT_BUFFER );
                    ret = 0;
                }
            }
        }
        else
        {
            UINT codepage = CP_ACP;
            if (!(lctype & LOCALE_USE_CP_ACP)) codepage = get_lcid_codepage( lcid );
            ret = WideCharToMultiByte( codepage, 0, bufferW, ret, buffer, len, NULL, NULL );
        }
    }
    HeapFree( GetProcessHeap(), 0, bufferW );
    return ret;
}


/*
 * @implemented
 */
LANGID STDCALL
GetSystemDefaultLangID(VOID)
{
  return LANGIDFROMLCID(GetSystemDefaultLCID());
}


/*
 * @implemented
 */
LCID STDCALL
GetSystemDefaultLCID(VOID)
{
  LCID lcid;

  NtQueryDefaultLocale(FALSE, &lcid);

  return lcid;
}


/*
 * @implemented
 */
LANGID STDCALL
GetSystemDefaultUILanguage(VOID)
{
  LANGID LanguageId;
  NTSTATUS Status;

  Status = NtQueryInstallUILanguage(&LanguageId);
  if (!NT_SUCCESS(Status))
    {
      SetLastErrorByStatus(Status);
      return 0;
    }

  return LanguageId;
}


/*
 * @implemented
 */
LCID STDCALL
GetThreadLocale(VOID)
{
  return NtCurrentTeb()->CurrentLocale;
}


/*
 * @implemented
 */
LANGID STDCALL
GetUserDefaultLangID(VOID)
{
  return LANGIDFROMLCID(GetUserDefaultLCID());
}


/*
 * @implemented
 */
LCID STDCALL
GetUserDefaultLCID(VOID)
{
  LCID lcid;
  NTSTATUS Status;

  Status = NtQueryDefaultLocale(TRUE, &lcid);
  if (!NT_SUCCESS(Status))
    {
      SetLastErrorByStatus(Status);
      return 0;
    }

  return lcid;
}


/*
 * @implemented
 */
LANGID STDCALL
GetUserDefaultUILanguage(VOID)
{
  LANGID LangId;
  NTSTATUS Status;

  Status = NtQueryDefaultUILanguage(&LangId);
  if (!NT_SUCCESS(Status))
    {
      SetLastErrorByStatus(Status);
      return 0;
    }

  return LangId;
}


/*
 * @unimplemented
 */
GEOID
STDCALL
GetUserGeoID(
    GEOCLASS    GeoClass)
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}


/*
 * @unimplemented
 */
BOOL
STDCALL
IsValidLanguageGroup(
    LGRPID  LanguageGroup,
    DWORD   dwFlags)
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}


/******************************************************************************
 *           IsValidLocale
 *
 * Determine if a locale is valid.
 *
 * PARAMS
 *  Locale  [I] LCID of the locale to check
 *  dwFlags [I] LCID_SUPPORTED = Valid
 *              LCID_INSTALLED = Valid and installed on the system
 *
 * RETURN
 *  TRUE,  if Locale is valid,
 *  FALSE, otherwise.
 *
 * @implemented
 */
BOOL STDCALL
IsValidLocale(LCID Locale,
	      DWORD dwFlags)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
  WCHAR ValueNameBuffer[9];
  UNICODE_STRING KeyName;
  UNICODE_STRING ValueName;
  ULONG KeyInfoSize;
  ULONG ReturnedSize;
  HANDLE KeyHandle;
  PWSTR ValueData;
  NTSTATUS Status;

  DPRINT("IsValidLocale() called\n");

  if ((dwFlags & ~(LCID_SUPPORTED | LCID_INSTALLED)) ||
      (dwFlags == (LCID_SUPPORTED | LCID_INSTALLED)))
    {
      DPRINT("Invalid flags: %lx\n", dwFlags);
      return FALSE;
    }

  if (Locale & 0xFFFF0000)
    {
      RtlInitUnicodeString(&KeyName,
			   L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Locale\\Alternate Sorts");
    }
  else
    {
      RtlInitUnicodeString(&KeyName,
			   L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Locale");
    }

  InitializeObjectAttributes(&ObjectAttributes,
			     &KeyName,
			     OBJ_CASE_INSENSITIVE,
			     NULL,
			     NULL);

  Status = NtOpenKey(&KeyHandle,
		     KEY_QUERY_VALUE,
		     &ObjectAttributes);
  if (!NT_SUCCESS(Status))
    {
      DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
      return FALSE;
    }

  swprintf(ValueNameBuffer, L"%08lx", (ULONG)Locale);
  RtlInitUnicodeString(&ValueName, ValueNameBuffer);

  KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4 * sizeof(WCHAR);
  KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(),
			    HEAP_ZERO_MEMORY,
			    KeyInfoSize);
  if (KeyInfo == NULL)
    {
      DPRINT("RtlAllocateHeap() failed (Status %lx)\n", Status);
      NtClose(KeyHandle);
      return FALSE;
    }

  Status = NtQueryValueKey(KeyHandle,
			   &ValueName,
			   KeyValuePartialInformation,
			   KeyInfo,
			   KeyInfoSize,
			   &ReturnedSize);
  NtClose(KeyHandle);

  if (!NT_SUCCESS(Status))
    {
      DPRINT("NtQueryValueKey() failed (Status %lx)\n", Status);
      RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
      return FALSE;
    }

  if (dwFlags & LCID_SUPPORTED)
    {
      DPRINT("Locale is supported\n");
      RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
      return TRUE;
    }

  ValueData = (PWSTR)&KeyInfo->Data[0];
  if ((dwFlags & LCID_INSTALLED) &&
      (KeyInfo->Type == REG_SZ) &&
      (KeyInfo->DataLength == 2 * sizeof(WCHAR)) &&
      (ValueData[0] == L'1'))
    {
      DPRINT("Locale is supported and installed\n");
      RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
      return TRUE;
    }

  RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);

  DPRINT("IsValidLocale() called\n");

  return FALSE;
}


/*
 * @unimplemented
 */
int
STDCALL
LCMapStringA (
    LCID    Locale,
    DWORD   dwMapFlags,
    LPCSTR  lpSrcStr,
    int cchSrc,
    LPSTR   lpDestStr,
    int cchDest
    )
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}


/*
 * @unimplemented
 */
int
STDCALL
LCMapStringW (
    LCID    Locale,
    DWORD   dwMapFlags,
    LPCWSTR lpSrcStr,
    int cchSrc,
    LPWSTR  lpDestStr,
    int cchDest
    )
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}


/*
 * @unimplemented
 */
BOOL
STDCALL
SetCalendarInfoA(
    LCID     Locale,
    CALID    Calendar,
    CALTYPE  CalType,
    LPCSTR  lpCalData)
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}

/*
 * @unimplemented
 */
BOOL
STDCALL
SetCalendarInfoW(
    LCID     Locale,
    CALID    Calendar,
    CALTYPE  CalType,
    LPCWSTR  lpCalData)
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}


/*
 * @unimplemented
 */
BOOL
STDCALL
SetLocaleInfoA (
    LCID    Locale,
    LCTYPE  LCType,
    LPCSTR  lpLCData
    )
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}


/*
 * @unimplemented
 */
BOOL
STDCALL
SetLocaleInfoW (
    LCID    Locale,
    LCTYPE  LCType,
    LPCWSTR lpLCData
    )
{
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}


/**********************************************************************
 * @implemented
 * RIPPED FROM WINE's dlls\kernel\locale.c rev 1.42
 *
 *           SetThreadLocale    (KERNEL32.@)
 *
 * Set the current threads locale.
 *
 * PARAMS
 *  lcid [I] LCID of the locale to set
 *
 * RETURNS
 *  Success: TRUE. The threads locale is set to lcid.
 *  Failure: FALSE. Use GetLastError() to determine the cause.
 *
 */
BOOL WINAPI SetThreadLocale( LCID lcid )
{
    DPRINT("SetThreadLocale(0x%04lX)\n", lcid);

    lcid = ConvertDefaultLocale(lcid);

    if (lcid != GetThreadLocale())
    {
        if (!IsValidLocale(lcid, LCID_SUPPORTED))
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }

        NtCurrentTeb()->CurrentLocale = lcid;
        /* FIXME: NtCurrentTeb()->code_page = get_lcid_codepage( lcid );
         * Wine save the acp for easy/fast access, but ROS has no such Teb member.
         * Maybe add this member to ros as well?
         */

        /*
        Lag test app for 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -