[PATCH 3/3] kernel32: Handle GEO_ID and GEO_NAME in GetGeoInfoW(), fix UN format.
João Diogo Ferreira
devilj at outlook.pt
Sun Nov 17 12:25:31 CST 2019
UN codes are always formatted in groups of three digits in Windows.
Also added more geotypes to the list of cases known but unhandled.
Signed-off-by: João Diogo Craveiro Ferreira <devilj at outlook.pt>
---
dlls/kernel32/locale.c | 46 ++++++++++++++++++++++++++++++++----
dlls/kernel32/tests/locale.c | 31 ++++++++++++++++++++++++
2 files changed, 73 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 5ee50272e7..2001a5b940 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -4106,6 +4106,33 @@ BOOL WINAPI SetUserGeoID(GEOID geoid)
/******************************************************************************
* GetGeoInfoW (KERNEL32.@)
+ *
+ * Retrieves information about a geographic location by its GeoID.
+ *
+ * PARAMS
+ * geoid [I] The GeoID of the location of interest.
+ * geotype [I] The type of information to be retrieved (SYSGEOTYPE enum from "winnls.h").
+ * data [O] The output buffer to store the information.
+ * data_len [I] The length of the buffer, measured in WCHARs and including the null terminator.
+ * lang [I] Language identifier. Must be 0 unless geotype is GEO_RFC1766 or GEO_LCID.
+ *
+ * RETURNS
+ * SUCCESS: The number of WCHARs (including null) written to the buffer -or-
+ * if no buffer was provided, the minimum length required to hold the full data.
+ * FAILURE: 0. Call GetLastError() to determine the cause.
+ *
+ * NOTES
+ * On failure, GetLastError() will return one of the following values:
+ * - ERROR_INVALID_PARAMETER: the GeoID provided was invalid.
+ * - ERROR_INVALID_FLAGS: the specified geotype was invalid.
+ * - ERROR_INSUFFICIENT_BUFFER: the provided buffer was too small to hold the full data.
+ * - ERROR_CALL_NOT_IMPLEMENTED: (Wine implementation) we don't handle that geotype yet.
+ *
+ * The list of available GeoIDs can be retrieved with EnumSystemGeoID().
+ *
+ * TODO
+ * Currently, we only handle the following geotypes: GEO_ID, GEO_NATION, GEO_ISO_UN_NUMBER,
+ * GEO_ISO2, GEO_ISO3 and GEO_NAME.
*/
INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len, LANGID lang)
{
@@ -4113,7 +4140,8 @@ INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len,
WCHAR buffW[12];
const WCHAR *str = buffW;
int len;
- static const WCHAR fmtW[] = {'%','d',0};
+ static const WCHAR id_fmtW[] = {'%','d',0};
+ static const WCHAR un_fmtW[] = {'%','0','3','d',0};
TRACE("%d %d %p %d %d\n", geoid, geotype, data, data_len, lang);
@@ -4123,14 +4151,15 @@ INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len,
}
switch (geotype) {
+ case GEO_ID:
case GEO_NATION:
- sprintfW(buffW, fmtW, ptr->id);
+ sprintfW(buffW, id_fmtW, ptr->id);
break;
case GEO_ISO_UN_NUMBER:
- sprintfW(buffW, fmtW, ptr->uncode);
+ sprintfW(buffW, un_fmtW, ptr->uncode);
break;
case GEO_PARENT:
- sprintfW(buffW, fmtW, ptr->parent);
+ sprintfW(buffW, id_fmtW, ptr->parent);
break;
case GEO_ISO2:
str = ptr->iso2W;
@@ -4138,6 +4167,12 @@ INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len,
case GEO_ISO3:
str = ptr->iso3W;
break;
+ case GEO_NAME:
+ if (ptr->uncode && !strcmpW((WCHAR[]){'X','X',0}, ptr->iso2W))
+ sprintfW(buffW, un_fmtW, ptr->uncode);
+ else
+ str = ptr->iso2W;
+ break;
case GEO_RFC1766:
case GEO_LCID:
case GEO_FRIENDLYNAME:
@@ -4146,6 +4181,9 @@ INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len,
case GEO_OFFICIALLANGUAGES:
case GEO_LATITUDE:
case GEO_LONGITUDE:
+ case GEO_DIALINGCODE:
+ case GEO_CURRENCYCODE:
+ case GEO_CURRENCYSYMBOL:
FIXME("type %d is not supported\n", geotype);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 81e74531ea..432d76b396 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -4798,6 +4798,17 @@ static void test_GetGeoInfo(void)
ok(ret == 4, "got %d\n", ret);
ok(!strcmp(buffA, "203"), "got %s\n", buffA);
+ /* GEO_ID should behave like GEO_NATION */
+ buffA[0] = 0;
+ ret = pGetGeoInfoA(203, GEO_ID, buffA, 20, 0);
+ if (ret)
+ {
+ ok(ret == 4, "got %d\n", ret);
+ ok(!strcmp(buffA, "203"), "got %s\n", buffA);
+ }
+ else
+ win_skip("GEO_ID not supported.\n");
+
/* GEO_PARENT */
buffA[0] = 0;
ret = pGetGeoInfoA(203, GEO_PARENT, buffA, 20, 0);
@@ -4819,6 +4830,26 @@ static void test_GetGeoInfo(void)
ok(!strcmp(buffA, "643"), "got %s\n", buffA);
}
+ buffA[0] = 0;
+ ret = pGetGeoInfoA(193, GEO_NAME, buffA, 20, 0); /* LOCATION_NATION */
+ if (ret == 0)
+ win_skip("GEO_NAME not supported.\n");
+ else
+ {
+ ok(ret == 3, "expected ret == 3, got %d", ret);
+ ok(!strcmp(buffA, "PT"), "expected PT, got %s\n", buffA);
+
+ buffA[0] = 0;
+ ret = pGetGeoInfoA(39070, GEO_NAME, buffA, 20, 0); /* LOCATION_REGION */
+ ok(ret == 4, "expected ret == 4, got %d", ret);
+ ok(!strcmp(buffA, "001"), "expected 001, got %s\n", buffA);
+
+ buffA[0] = 0;
+ ret = pGetGeoInfoA(333, GEO_NAME, buffA, 20, 0); /* LOCATION_BOTH */
+ ok(ret == 3, "expected ret == 3, got %d", ret);
+ ok(!strcmp(buffA, "AN"), "expected AN, got %s\n", buffA);
+ }
+
/* try invalid type value */
SetLastError(0xdeadbeef);
ret = pGetGeoInfoA(203, GEO_ID + 1, NULL, 0, 0);
--
2.24.0
More information about the wine-devel
mailing list