<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div>Because I have the attention span of a goldfish, I forgot to update one doc.<br>
I'll fix that in a separate patch (if this one is approved) or next revision (if explictly rejected).<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>De:</b> Jo�o Diogo Ferreira <devilj@outlook.pt><br>
<b>Enviado:</b> 6 de novembro de 2019 23:33<br>
<b>Para:</b> wine-devel@winehq.org <wine-devel@winehq.org><br>
<b>Cc:</b> Jo�o Diogo Ferreira <devilj@outlook.pt><br>
<b>Assunto:</b> [PATCH v5 3/7] kernel32: Implement SetUserGeoName().</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">SetUserGeoName() and SetUserGeoID() are now implemented<br>
by the same internal function, since they behave the same<br>
(they only differ in the arguments they take).<br>
<br>
The new UN codes (required for SetUserGeoName()) were tested<br>
and confirmed to match with Windows 10 v1909.<br>
<br>
Signed-off-by: Jo�o Diogo Craveiro Ferreira <devilj@outlook.pt><br>
---<br>
Supersedes: 172369<br>
V5: Move doc of SetUserGeoID() to previous patch.<br>
---<br>
dlls/kernel32/kernel32.spec | 1 +<br>
dlls/kernel32/locale.c | 277 ++++++++++++++++++++++++++++--------<br>
include/winnls.h | 1 +<br>
3 files changed, 222 insertions(+), 57 deletions(-)<br>
<br>
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec<br>
index 23c25b7acd..9898bdec6e 100644<br>
--- a/dlls/kernel32/kernel32.spec<br>
+++ b/dlls/kernel32/kernel32.spec<br>
@@ -1469,6 +1469,7 @@<br>
@ stdcall -arch=x86_64 SetUmsThreadInformation(ptr long ptr long)<br>
@ stdcall -import SetUnhandledExceptionFilter(ptr)<br>
@ stdcall SetUserGeoID(long)<br>
+@ stdcall SetUserGeoName(wstr)<br>
@ stub SetVDMCurrentDirectories<br>
@ stdcall SetVolumeLabelA(str str)<br>
@ stdcall SetVolumeLabelW(wstr wstr)<br>
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c<br>
index cff06c6b6a..5731f42cdf 100644<br>
--- a/dlls/kernel32/locale.c<br>
+++ b/dlls/kernel32/locale.c<br>
@@ -3889,7 +3889,7 @@ static const struct geoinfo_t geoinfodata[] = {<br>
{ 305, {'X','X',0}, {'X','X',0}, 161832256 }, /* Baker Island */<br>
{ 306, {'B','V',0}, {'B','V','T',0}, 39070, 74 }, /* Bouvet Island */<br>
{ 307, {'K','Y',0}, {'C','Y','M',0}, 10039880, 136 }, /* Cayman Islands */<br>
- { 308, {'X','X',0}, {'X','X',0}, 10210824, 0, LOCATION_BOTH }, /* Channel Islands */<br>
+ { 308, {'X','X',0}, {'X','X',0}, 10210824, 830, LOCATION_BOTH }, /* Channel Islands */<br>
{ 309, {'C','X',0}, {'C','X','R',0}, 12, 162 }, /* Christmas Island */<br>
{ 310, {'X','X',0}, {'X','X',0}, 27114 }, /* Clipperton Island */<br>
{ 311, {'C','C',0}, {'C','C','K',0}, 10210825, 166 }, /* Cocos (Keeling) Islands */<br>
@@ -3929,47 +3929,54 @@ static const struct geoinfo_t geoinfodata[] = {<br>
{ 349, {'T','C',0}, {'T','C','A',0}, 10039880, 796 }, /* Turks and Caicos Islands */<br>
{ 351, {'V','G',0}, {'V','G','B',0}, 10039880, 92 }, /* Virgin Islands, British */<br>
{ 352, {'W','F',0}, {'W','L','F',0}, 26286, 876 }, /* Wallis and Futuna */<br>
- { 742, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Africa */<br>
- { 2129, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Asia */<br>
- { 10541, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Europe */<br>
+ { 742, {'X','X',0}, {'X','X',0}, 39070, 2, LOCATION_REGION }, /* Africa */<br>
+ { 2129, {'X','X',0}, {'X','X',0}, 39070, 142, LOCATION_REGION }, /* Asia */<br>
+ { 10541, {'X','X',0}, {'X','X',0}, 39070, 150, LOCATION_REGION }, /* Europe */<br>
{ 15126, {'I','M',0}, {'I','M','N',0}, 10039882, 833 }, /* Man, Isle of */<br>
{ 19618, {'M','K',0}, {'M','K','D',0}, 47610, 807 }, /* Macedonia, Former Yugoslav Republic of */<br>
- { 20900, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Melanesia */<br>
- { 21206, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Micronesia */<br>
+ { 20900, {'X','X',0}, {'X','X',0}, 27114, 54, LOCATION_REGION }, /* Melanesia */<br>
+ { 21206, {'X','X',0}, {'X','X',0}, 27114, 57, LOCATION_REGION }, /* Micronesia */<br>
{ 21242, {'X','X',0}, {'X','X',0}, 161832256 }, /* Midway Islands */<br>
- { 23581, {'X','X',0}, {'X','X',0}, 10026358, 0, LOCATION_REGION }, /* Northern America */<br>
- { 26286, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Polynesia */<br>
- { 27082, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* Central America */<br>
- { 27114, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Oceania */<br>
+ { 23581, {'X','X',0}, {'X','X',0}, 10026358, 21, LOCATION_REGION }, /* Northern America */<br>
+ { 26286, {'X','X',0}, {'X','X',0}, 27114, 61, LOCATION_REGION }, /* Polynesia */<br>
+ { 27082, {'X','X',0}, {'X','X',0}, 161832257, 13, LOCATION_REGION }, /* Central America */<br>
+ { 27114, {'X','X',0}, {'X','X',0}, 39070, 9, LOCATION_REGION }, /* Oceania */<br>
{ 30967, {'S','X',0}, {'S','X','M',0}, 10039880, 534 }, /* Sint Maarten (Dutch part) */<br>
- { 31396, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* South America */<br>
+ { 31396, {'X','X',0}, {'X','X',0}, 161832257, 5, LOCATION_REGION }, /* South America */<br>
{ 31706, {'M','F',0}, {'M','A','F',0}, 10039880, 663 }, /* Saint Martin (French part) */<br>
- { 39070, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* World */<br>
- { 42483, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Western Africa */<br>
- { 42484, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Middle Africa */<br>
- { 42487, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Northern Africa */<br>
- { 47590, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Central Asia */<br>
- { 47599, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* South-Eastern Asia */<br>
- { 47600, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Eastern Asia */<br>
- { 47603, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Eastern Africa */<br>
- { 47609, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Eastern Europe */<br>
- { 47610, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Southern Europe */<br>
- { 47611, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Middle East */<br>
- { 47614, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Southern Asia */<br>
+ { 39070, {'X','X',0}, {'X','X',0}, 39070, 1, LOCATION_REGION }, /* World */<br>
+ { 42483, {'X','X',0}, {'X','X',0}, 742, 11, LOCATION_REGION }, /* Western Africa */<br>
+ { 42484, {'X','X',0}, {'X','X',0}, 742, 17, LOCATION_REGION }, /* Middle Africa */<br>
+ { 42487, {'X','X',0}, {'X','X',0}, 742, 15, LOCATION_REGION }, /* Northern Africa */<br>
+ { 47590, {'X','X',0}, {'X','X',0}, 2129, 143, LOCATION_REGION }, /* Central Asia */<br>
+ { 47599, {'X','X',0}, {'X','X',0}, 2129, 35, LOCATION_REGION }, /* South-Eastern Asia */<br>
+ { 47600, {'X','X',0}, {'X','X',0}, 2129, 30, LOCATION_REGION }, /* Eastern Asia */<br>
+ { 47603, {'X','X',0}, {'X','X',0}, 742, 14, LOCATION_REGION }, /* Eastern Africa */<br>
+ { 47609, {'X','X',0}, {'X','X',0}, 10541, 151, LOCATION_REGION }, /* Eastern Europe */<br>
+ { 47610, {'X','X',0}, {'X','X',0}, 10541, 39, LOCATION_REGION }, /* Southern Europe */<br>
+ { 47611, {'X','X',0}, {'X','X',0}, 2129, 145, LOCATION_REGION }, /* Middle East */<br>
+ { 47614, {'X','X',0}, {'X','X',0}, 2129, 34, LOCATION_REGION }, /* Southern Asia */<br>
{ 7299303, {'T','L',0}, {'T','L','S',0}, 47599, 626 }, /* Democratic Republic of Timor-Leste */<br>
- { 10026358, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Americas */<br>
+ { 10026358, {'X','X',0}, {'X','X',0}, 39070, 19, LOCATION_REGION }, /* Americas */<br>
{ 10028789, {'A','X',0}, {'A','L','A',0}, 10039882, 248 }, /* �land Islands */<br>
- { 10039880, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* Caribbean */<br>
- { 10039882, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Northern Europe */<br>
- { 10039883, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Southern Africa */<br>
- { 10210824, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Western Europe */<br>
- { 10210825, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Australia and New Zealand */<br>
+ { 10039880, {'X','X',0}, {'X','X',0}, 161832257, 29, LOCATION_REGION }, /* Caribbean */<br>
+ { 10039882, {'X','X',0}, {'X','X',0}, 10541, 154, LOCATION_REGION }, /* Northern Europe */<br>
+ { 10039883, {'X','X',0}, {'X','X',0}, 742, 18, LOCATION_REGION }, /* Southern Africa */<br>
+ { 10210824, {'X','X',0}, {'X','X',0}, 10541, 155, LOCATION_REGION }, /* Western Europe */<br>
+ { 10210825, {'X','X',0}, {'X','X',0}, 27114, 53, LOCATION_REGION }, /* Australia and New Zealand */<br>
{ 161832015, {'B','L',0}, {'B','L','M',0}, 10039880, 652 }, /* Saint Barth�lemy */<br>
{ 161832256, {'U','M',0}, {'U','M','I',0}, 27114, 581 }, /* U.S. Minor Outlying Islands */<br>
- { 161832257, {'X','X',0}, {'X','X',0}, 10026358, 0, LOCATION_REGION }, /* Latin America and the Caribbean */<br>
+ { 161832257, {'X','X',0}, {'X','X',0}, 10026358, 419, LOCATION_REGION }, /* Latin America and the Caribbean */<br>
};<br>
<br>
-static const struct geoinfo_t *get_geoinfo_dataptr(GEOID geoid)<br>
+static const WCHAR geoname_uncode_fmtW[] = {'%','0','3','i',0};<br>
+<br>
+/******************************************************************************<br>
+ * get_geoinfoptr_by_id<br>
+ *<br>
+ * Returns a pointer to a geoinfo struct by finding its GeoID.<br>
+ */<br>
+static const struct geoinfo_t *get_geoinfoptr_by_id(GEOID geoid)<br>
{<br>
int min, max;<br>
<br>
@@ -3994,6 +4001,91 @@ static const struct geoinfo_t *get_geoinfo_dataptr(GEOID geoid)<br>
return NULL;<br>
}<br>
<br>
+/******************************************************************************<br>
+ * get_geoinfoptr_by_str<br>
+ *<br>
+ * Returns a pointer to a geoinfo struct by<br>
+ * matching a string to the specified geotype.<br>
+ */<br>
+<br>
+static const struct geoinfo_t *get_geoinfoptr_by_str(const WCHAR *str, GEOTYPE geotype)<br>
+{<br>
+ int num;<br>
+<br>
+ if (!str)<br>
+ return NULL;<br>
+<br>
+ switch (geotype)<br>
+ {<br>
+ case GEO_ISO2:<br>
+ for (int i = 0; i < ARRAY_SIZE(geoinfodata); i++)<br>
+ if (!(strcmpW(geoinfodata[i].iso2W, str))) return &geoinfodata[i];<br>
+ break;<br>
+ case GEO_ISO_UN_NUMBER:<br>
+ if (!(num = atoiW(str))) return NULL;<br>
+ for (int i = 0; i < ARRAY_SIZE(geoinfodata); i++)<br>
+ if (num == geoinfodata[i].uncode)<br>
+ return geoinfodata[i].kind == LOCATION_REGION ? &geoinfodata[i] : NULL;<br>
+ break;<br>
+ }<br>
+ return NULL;<br>
+}<br>
+<br>
+/******************************************************************************<br>
+ * get_geoinfoptr_by_name<br>
+ *<br>
+ * Parse and fix a geoname and return a pointer<br>
+ * to the matching geoinfo struct.<br>
+ */<br>
+<br>
+static inline const struct geoinfo_t *get_geoinfoptr_by_name(const WCHAR *name)<br>
+{<br>
+ WCHAR buffer[3];<br>
+ int good = 0, len = 0;<br>
+<br>
+ if (!name)<br>
+ return NULL;<br>
+<br>
+ /* Check if str is a two-letter country code (and make it uppercase) */<br>
+ for (int i = 0; i <= 2; i++)<br>
+ if ((name[i] <= 127 && isalphaW(name[i])))<br>
+ {<br>
+ buffer[i] = toupperW(name[i]);<br>
+ good++;<br>
+ }<br>
+ else<br>
+ {<br>
+ if (!name[i])<br>
+ {<br>
+ buffer[i] = 0;<br>
+ len = i;<br>
+ }<br>
+ break;<br>
+ }<br>
+<br>
+ if (good == 2 && len == 2)<br>
+ return get_geoinfoptr_by_str(buffer, GEO_ISO2);<br>
+<br>
+ /* Now check if it's a three-digit code. */<br>
+ good = 0;<br>
+ len = 0;<br>
+<br>
+ for (int i = 0; i <= 3; i++)<br>
+ if (isdigitW(name[i]))<br>
+ good++;<br>
+ else<br>
+ {<br>
+ if (!name[i])<br>
+ len = i;<br>
+ break;<br>
+ }<br>
+<br>
+ if (good == 3 && len == 3)<br>
+ return get_geoinfoptr_by_str(name, GEO_ISO_UN_NUMBER);<br>
+<br>
+ return NULL;<br>
+}<br>
+<br>
/******************************************************************************<br>
* GetUserGeoID (KERNEL32.@)<br>
*<br>
@@ -4050,28 +4142,25 @@ GEOID WINAPI GetUserGeoID(GEOCLASS geoclass)<br>
}<br>
<br>
/******************************************************************************<br>
- * SetUserGeoID (KERNEL32.@)<br>
- *<br>
- * Sets the ID of the user's geographic location.<br>
- *<br>
- * PARAMS<br>
- * geoid [I] The geographic ID to be set.<br>
- *<br>
- * RETURNS<br>
- * SUCCESS: TRUE.<br>
- * FAILURE: FALSE. GetLastError() will return ERROR_INVALID_PARAMETER if the ID was invalid.<br>
- */<br>
-BOOL WINAPI SetUserGeoID(GEOID geoid)<br>
+* set_geo_reg<br>
+*<br>
+* Does the heavy lifting for SetUserGeoName() and SetUserGeoID().<br>
+*<br>
+* The return value and last error set here can (and probably should)<br>
+* be returned to the callers of those two functions.<br>
+*/<br>
+static int set_geo_reg(const struct geoinfo_t *geoinfo)<br>
{<br>
- const struct geoinfo_t *geoinfo = get_geoinfo_dataptr(geoid);<br>
static const WCHAR geoW[] = {'G','e','o',0};<br>
static const WCHAR nationW[] = {'N','a','t','i','o','n',0};<br>
static const WCHAR regionW[] = {'R','e','g','i','o','n',0};<br>
- static const WCHAR formatW[] = {'%','i',0};<br>
- UNICODE_STRING nameW, keyW;<br>
- WCHAR bufferW[10];<br>
+ static const WCHAR nameW[] = {'N','a','m','e',0};<br>
+ static const WCHAR id_formatW[] = {'%','i',0};<br>
+ UNICODE_STRING geokeyW, idkeyW, namekeyW;<br>
+ WCHAR id_buffer[10], name_buffer[4];<br>
OBJECT_ATTRIBUTES attr;<br>
HANDLE hkey;<br>
+ RtlInitUnicodeString(&geokeyW, geoW);<br>
<br>
if (!geoinfo)<br>
{<br>
@@ -4084,16 +4173,11 @@ BOOL WINAPI SetUserGeoID(GEOID geoid)<br>
<br>
attr.Length = sizeof(attr);<br>
attr.RootDirectory = hkey;<br>
- attr.ObjectName = &nameW;<br>
+ attr.ObjectName = &geokeyW;<br>
attr.Attributes = 0;<br>
attr.SecurityDescriptor = NULL;<br>
attr.SecurityQualityOfService = NULL;<br>
- RtlInitUnicodeString(&nameW, geoW);<br>
-<br>
- if (geoinfo->kind == LOCATION_NATION)<br>
- RtlInitUnicodeString(&keyW, nationW);<br>
- else<br>
- RtlInitUnicodeString(&keyW, regionW);<br>
+ RtlInitUnicodeString(&geokeyW, geoW);<br>
<br>
if (NtCreateKey(&hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL) != STATUS_SUCCESS)<br>
{<br>
@@ -4101,13 +4185,92 @@ BOOL WINAPI SetUserGeoID(GEOID geoid)<br>
return FALSE;<br>
}<br>
<br>
- sprintfW(bufferW, formatW, geoinfo->id);<br>
- NtSetValueKey(hkey, &keyW, 0, REG_SZ, bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR));<br>
+ /* Prepare GeoID */<br>
+ if (geoinfo->kind == LOCATION_NATION)<br>
+ RtlInitUnicodeString(&idkeyW, nationW);<br>
+ else<br>
+ RtlInitUnicodeString(&idkeyW, regionW);<br>
+<br>
+ sprintfW(id_buffer, id_formatW, geoinfo->id);<br>
+<br>
+ /* Now prepare geoname */<br>
+ RtlInitUnicodeString(&namekeyW, nameW);<br>
+<br>
+ if (geoinfo->kind == LOCATION_REGION)<br>
+ sprintfW(name_buffer, geoname_uncode_fmtW, geoinfo->uncode);<br>
+ else<br>
+ strcpyW(name_buffer, geoinfo->iso2W);<br>
+<br>
+ NtSetValueKey(hkey, &idkeyW, 0, REG_SZ, id_buffer,<br>
+ (strlenW(id_buffer) + 1) * sizeof(WCHAR));<br>
+ NtSetValueKey(hkey, &namekeyW, 0, REG_SZ, name_buffer,<br>
+ (strlenW(name_buffer) + 1) * sizeof(WCHAR));<br>
+<br>
+ TRACE("Set %s to ID %d; set Name to %s.\n",<br>
+ wine_dbgstr_w(idkeyW.Buffer), geoinfo->id, wine_dbgstr_w(name_buffer));<br>
+<br>
NtClose(attr.RootDirectory);<br>
NtClose(hkey);<br>
return TRUE;<br>
}<br>
<br>
+/******************************************************************************<br>
+ * SetUserGeoID (KERNEL32.@)<br>
+ *<br>
+ * Sets the ID of the user's geographic location.<br>
+ *<br>
+ * PARAMS<br>
+ * geoid [I] The geographic ID to be set.<br>
+ *<br>
+ * RETURNS<br>
+ * SUCCESS: TRUE.<br>
+ * FAILURE: FALSE. GetLastError() will return ERROR_INVALID_PARAMETER if the ID was invalid.<br>
+ *<br>
+ * NOTES<br>
+ * On success, the geographic name will be set to the location of the specified ID.<br>
+ */<br>
+BOOL WINAPI SetUserGeoID(GEOID geoid)<br>
+{<br>
+ TRACE("(%d)\n", geoid);<br>
+ return set_geo_reg(get_geoinfoptr_by_id(geoid));<br>
+}<br>
+<br>
+/******************************************************************************<br>
+ * SetUserGeoName (KERNEL32.@)<br>
+ *<br>
+ * Sets the name of the user's geographic location.<br>
+ *<br>
+ * This name is a two-letter ISO 3166 country code<br>
+ * or a three-digit UN M.49 code for anything other than countries (e.g. continents).<br>
+ *<br>
+ * PARAMS<br>
+ * geoname [I] The name to be set.<br>
+ *<br>
+ * RETURNS<br>
+ * SUCCESS: TRUE.<br>
+ * FAILURE: FALSE. Call GetLastError() to determine the cause.<br>
+ *<br>
+ * NOTES<br>
+ * On success, the geographic ID for the relevant class will be set to<br>
+ * the location of the specified name.<br>
+ *<br>
+ * On failure, GetLastError() will return one of the following values:<br>
+ * - ERROR_INVALID_PARAMETER: the specified GeoID was invalid.<br>
+ * - ERROR_INTERNAL_ERROR: an internal error prevented Wine from setting the name.<br>
+ */<br>
+BOOL WINAPI SetUserGeoName(WCHAR *geoname)<br>
+{<br>
+ if (!geoname || !*geoname)<br>
+ {<br>
+ TRACE("(%p = (null))\n", geoname);<br>
+ SetLastError(ERROR_INVALID_PARAMETER);<br>
+ return FALSE;<br>
+ }<br>
+<br>
+ TRACE("(%p = %s)\n", geoname, wine_dbgstr_w(geoname));<br>
+ return set_geo_reg(get_geoinfoptr_by_name(geoname));<br>
+}<br>
+<br>
/******************************************************************************<br>
* GetGeoInfoW (KERNEL32.@)<br>
*/<br>
@@ -4121,7 +4284,7 @@ INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len,<br>
<br>
TRACE("%d %d %p %d %d\n", geoid, geotype, data, data_len, lang);<br>
<br>
- if (!(ptr = get_geoinfo_dataptr(geoid))) {<br>
+ if (!(ptr = get_geoinfoptr_by_id(geoid))) {<br>
SetLastError(ERROR_INVALID_PARAMETER);<br>
return 0;<br>
}<br>
diff --git a/include/winnls.h b/include/winnls.h<br>
index e810c44af7..4f84c64f81 100644<br>
--- a/include/winnls.h<br>
+++ b/include/winnls.h<br>
@@ -968,6 +968,7 @@ WINBASEAPI BOOL WINAPI SetLocaleInfoW(LCID,LCTYPE,LPCWSTR);<br>
WINBASEAPI BOOL WINAPI SetThreadLocale(LCID);<br>
WINBASEAPI LANGID WINAPI SetThreadUILanguage(LANGID);<br>
WINBASEAPI BOOL WINAPI SetUserGeoID(GEOID);<br>
+WINBASEAPI BOOL WINAPI SetUserGeoName(WCHAR*);<br>
WINBASEAPI INT WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,INT,LPSTR,INT,LPCSTR,LPBOOL);<br>
WINBASEAPI INT WINAPI FindNLSStringEx(const WCHAR *,DWORD,const WCHAR *,INT,const WCHAR *,INT,INT *,NLSVERSIONINFO *,void *,LPARAM);<br>
<br>
-- <br>
2.23.0<br>
<br>
</div>
</span></font></div>
</body>
</html>