[PATCH 05/12] kernel32: Implement SetUserGeoName(), add helper set_geo_reg().
João Diogo Ferreira
devilj at outlook.pt
Tue Oct 22 12:43:34 CDT 2019
The new helper implements behaviour for both
SetUserGeoName() and SetUserGeoID(), seeing as they behave the same.
Signed-off-by: João Diogo Craveiro Ferreira <devilj at outlook.pt>
---
dlls/kernel32/kernel32.spec | 1 +
dlls/kernel32/locale.c | 111 ++++++++++++++++++++++++++++++++----
include/winnls.h | 1 +
3 files changed, 103 insertions(+), 10 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 23c25b7acd..beebea9c1c 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1469,6 +1469,7 @@
@ stdcall -arch=x86_64 SetUmsThreadInformation(ptr long ptr long)
@ stdcall -import SetUnhandledExceptionFilter(ptr)
@ stdcall SetUserGeoID(long)
+@ stdcall SetUserGeoName(ptr)
@ stub SetVDMCurrentDirectories
@ stdcall SetVolumeLabelA(str str)
@ stdcall SetVolumeLabelW(wstr wstr)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index b582324978..4957e8df5e 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -4121,16 +4121,22 @@ GEOID WINAPI GetUserGeoID( GEOCLASS GeoClass )
}
/******************************************************************************
- * SetUserGeoID (KERNEL32.@)
+ * set_geo_reg
+ *
+ * Does the heavy lifting for SetUserGeoName() and SetUserGeoID().
+ *
+ * The return value and last error set here can (and probably should)
+ * be returned to the callers of those two functions.
*/
-BOOL WINAPI SetUserGeoID( GEOID GeoID )
+static int set_geo_reg(const struct geoinfo_t *geoinfo)
{
- const struct geoinfo_t *geoinfo = get_geoinfoptr_by_id(GeoID);
static const WCHAR nationW[] = {'N','a','t','i','o','n',0};
static const WCHAR regionW[] = {'R','e','g','i','o','n',0};
- static const WCHAR formatW[] = {'%','i',0};
- UNICODE_STRING keyW;
- WCHAR bufferW[10];
+ static const WCHAR nameW[] = {'N','a','m','e',0};
+ static const WCHAR id_formatW[] = {'%','i',0};
+ UNICODE_STRING idkeyW, namekeyW;
+ WCHAR geoidW[10], geonameW[4];
+ int namelen;
HANDLE hkey;
if (!geoinfo)
@@ -4144,17 +4150,102 @@ BOOL WINAPI SetUserGeoID( GEOID GeoID )
return FALSE;
}
+ /* Prepare GeoID */
if (geoinfo->kind == LOCATION_NATION)
- RtlInitUnicodeString( &keyW, nationW );
+ RtlInitUnicodeString(&idkeyW, nationW);
else
- RtlInitUnicodeString( &keyW, regionW );
+ RtlInitUnicodeString(&idkeyW, regionW);
+
+ sprintfW(geoidW, id_formatW, geoinfo->id);
+
+ /* Now prepare GeoName */
+ RtlInitUnicodeString( &namekeyW, nameW );
+
+ if (geoinfo->kind == LOCATION_REGION)
+ {
+ sprintfW(geonameW, geoname_uncode_fmtW, geoinfo->uncode);
+ namelen = 4;
+ }
+ else
+ {
+ strcpyW(geonameW, geoinfo->iso2W);
+ namelen = 3;
+ }
+
+ NtSetValueKey(hkey, &idkeyW, 0, REG_SZ, geoidW, (strlenW(geoidW) + 1) * sizeof(WCHAR));
+ NtSetValueKey(hkey, &namekeyW, 0, REG_SZ, geonameW, namelen * sizeof(WCHAR));
+
+ TRACE("Set %s to ID %d; set Name to %s\n",
+ wine_dbgstr_w(idkeyW.Buffer), geoinfo->id, wine_dbgstr_w(geonameW));
- sprintfW(bufferW, formatW, geoinfo->id);
- NtSetValueKey(hkey, &keyW, 0, REG_SZ, bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR));
NtClose(hkey);
return TRUE;
}
+/******************************************************************************
+ * SetUserGeoID (KERNEL32.@)
+ *
+ * Sets the ID of the user's geographic location.
+ *
+ * PARAMS
+ * GeoID [I] The geographic ID to be set.
+ *
+ * RETURNS
+ * SUCCESS: TRUE.
+ * FAILURE: FALSE. Call GetLastError() to determine the cause.
+ *
+ * NOTES
+ * On success, the geographic name will be set to the location of the specified GeoID.
+ *
+ * On failure, GetLastError() will return one of the following values:
+ * - ERROR_INVALID_PARAMETER: the specified GeoID was invalid.
+ * - ERROR_INTERNAL_ERROR: an internal error prevented Wine from setting the GeoID.
+ */
+BOOL WINAPI SetUserGeoID(GEOID GeoID)
+{
+ TRACE("(%d)\n", GeoID);
+ return set_geo_reg(get_geoinfoptr_by_id(GeoID));
+}
+
+/******************************************************************************
+ * SetUserGeoName (KERNEL32.@)
+ *
+ * Sets the name of the user's geographic location.
+ *
+ * This name is a two-letter ISO 3166 country code
+ * or a three-digit UN M.49 code for anything other than countries (e.g. continents).
+ *
+ * PARAMS
+ * geoName [I] The name to be set.
+ *
+ * RETURNS
+ * SUCCESS: TRUE.
+ * FAILURE: FALSE. Call GetLastError() to determine the cause.
+ *
+ * NOTES
+ * If you specify the UN code of a valid country, its two-letter ISO code
+ * will be used instead.
+ *
+ * On success, the geographic ID for the relevant class will be set to
+ * the location of the specified name.
+ *
+ * On failure, GetLastError() will return one of the following values:
+ * - ERROR_INVALID_PARAMETER: the specified GeoID was invalid.
+ * - ERROR_INTERNAL_ERROR: an internal error prevented Wine from setting the name.
+ */
+BOOL WINAPI SetUserGeoName(LPWSTR geoName)
+{
+ if (!geoName || !*geoName)
+ {
+ TRACE("(%p = (null))\n", geoName);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ TRACE("(%p = %s)\n", geoName, wine_dbgstr_w(geoName));
+ return set_geo_reg(get_geoinfoptr_by_name(geoName));
+}
+
/******************************************************************************
* GetGeoInfoW (KERNEL32.@)
*/
diff --git a/include/winnls.h b/include/winnls.h
index e810c44af7..3aeb47c9e4 100644
--- a/include/winnls.h
+++ b/include/winnls.h
@@ -968,6 +968,7 @@ WINBASEAPI BOOL WINAPI SetLocaleInfoW(LCID,LCTYPE,LPCWSTR);
WINBASEAPI BOOL WINAPI SetThreadLocale(LCID);
WINBASEAPI LANGID WINAPI SetThreadUILanguage(LANGID);
WINBASEAPI BOOL WINAPI SetUserGeoID(GEOID);
+WINBASEAPI BOOL WINAPI SetUserGeoName(LPWSTR);
WINBASEAPI INT WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,INT,LPSTR,INT,LPCSTR,LPBOOL);
WINBASEAPI INT WINAPI FindNLSStringEx(const WCHAR *,DWORD,const WCHAR *,INT,const WCHAR *,INT,INT *,NLSVERSIONINFO *,void *,LPARAM);
--
2.23.0
More information about the wine-devel
mailing list