Use ANSI when printing to the console. Fix the logic of LookupPrivilegeDisplayNameW.
Patch by Ismael Ferreras Morezuelas.

CORE-8965 #resolve #comment Committed in revision r65894. Thanks!


svn path=/trunk/; revision=65894
This commit is contained in:
Aleksandar Andrejevic
2014-12-29 16:20:00 +00:00
parent e6475301eb
commit 4037b3b7c0
6 changed files with 122 additions and 60 deletions
@@ -38,19 +38,19 @@ BEGIN
IDS_ERROR_INVALIDARG "FEHLER: Argument/Option ungültig - '%s'.\nGeben Sie ""WHOAMI /?"" ein, um die Syntax anzuzeigen.\n"
IDS_ERROR_NH_LIST "FEHLER: Option /NH kann nicht mit Format LIST verwendet werden.\nGeben Sie ""WHOAMI /?"" ein, um die Syntax anzuzeigen.\n"
IDS_HELP "BESCHREIBUNG:\n\
Ermittelt Benutzername, Gruppen und Berechtigungen für den aktuellen Benutzer auf dem lokalen System.\n\
Ohne Parameterangabe werden die aktuelle Domäne und Benutzername angezeigt.\n\
Ermittelt Benutzername, Gruppen und Berechtigungen für den aktuellen Benutzer auf dem lokalen System.\n\
Ohne Parameterangabe werden die aktuelle Domäne und Benutzername angezeigt.\n\
\n\
Gültige Ausgabeformate für den '/fo' Parameter sind 'CSV', 'LIST' und 'TABLE'.\n\
'/nh' legt fest, dass der Spaltenheader nicht in der Ausgabe angezeigt wird. Standardmäßig werden diese in einer TABLE angezeigt.\n\
Gültige Ausgabeformate für den '/fo' Parameter sind 'CSV', 'LIST' und 'TABLE'.\n\
'/nh' legt fest, dass der Spaltenheader nicht in der Ausgabe angezeigt wird. Standardmäßig werden diese in einer TABLE angezeigt.\n\
\n\
SYNTAX:\n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Format>] [/nh] \n\
whoami /all [/fo <Format>] [/nh] \n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Format>] [/nh] \n\
whoami /all [/fo <Format>] [/nh] \n\
\n\
BEISPIELE: \n\
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
END
@@ -38,19 +38,19 @@ BEGIN
IDS_ERROR_INVALIDARG "ERROR: Invalid argument/option - '%s'.\nType ""WHOAMI /?"" for usage.\n"
IDS_ERROR_NH_LIST "ERROR: /NH switch cannot be used with the LIST format.\nType ""WHOAMI /?"" for usage.\n"
IDS_HELP "DESCRIPTION:\n\
Display user, group and privileges information for the local logged-on user.\n\
If no arguments are provided, displays the current domain and user name.\n\
Display user, group and privileges information for the local logged-on user.\n\
If no arguments are provided, displays the current domain and user name.\n\
\n\
Available output formats for the '/fo' option are 'csv', 'list' and 'table'.\n\
Use '/nh' to hide headers. By default the data is displayed in a table.\n\
Available output formats for the '/fo' option are 'csv', 'list' and 'table'.\n\
Use '/nh' to hide headers. By default the data is displayed in a table.\n\
\n\
SYNTAX:\n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Format>] [/nh] \n\
whoami /all [/fo <Format>] [/nh] \n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Format>] [/nh] \n\
whoami /all [/fo <Format>] [/nh] \n\
\n\
EXAMPLES: \n\
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
END
@@ -39,20 +39,20 @@ BEGIN
IDS_ERROR_INVALIDARG "ERROR: Argumento u opción no válido - ""%s"".\nEscriba ""WHOAMI /?"" para su uso.\n"
IDS_ERROR_NH_LIST "ERROR: no se puede usar el modificador /NH con el formato LIST.\nEscriba ""WHOAMI /?"" para obtener detalles de uso.\n"
IDS_HELP "DESCRIPCIÓN:\n\
Muestra información sobre el usuario local, sus privilegios y grupos.\n\
Si no se añaden argumentos se mostrará el usuario y dominio actual.\n\
Muestra información sobre el usuario local, sus privilegios y grupos.\n\
Si no se añaden argumentos se mostrará el usuario y dominio actual.\n\
\n\
Los formatos disponibles para '/fo' son 'csv', 'list' y 'table'.\n\
Por defecto los datos se muestran en una tabla (opción 'table').\n\
Puedes utilizar '/nh' para ocultar los encabezados. \n\
Los formatos disponibles para '/fo' son 'csv', 'list' y 'table'.\n\
Por defecto los datos se muestran en una tabla (opción 'table').\n\
Puedes utilizar '/nh' para ocultar los encabezados. \n\
\n\
SINTAXIS:\n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Formato>] [/nh] \n\
whoami /all [/fo <Formato>] [/nh] \n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Formato>] [/nh] \n\
whoami /all [/fo <Formato>] [/nh] \n\
\n\
EJEMPLOS: \n\
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
END
@@ -38,19 +38,19 @@ BEGIN
IDS_ERROR_INVALIDARG "Erreur : Argument/option non valide - '%s'.\nTapez ""WHOAMI /?"" pour l'aide.\n"
IDS_ERROR_NH_LIST "Erreur : l'argument /NH ne peut pas être utilisé avec le format LIST.\nTapez ""WHOAMI /?"" pour l'aide.\n"
IDS_HELP "DESCRIPTION:\n\
Affiche les informations sur l'utilisateur, les groupes et les privilèges pour l'utilisateur actuellement connecté.\n\
Si aucun argument n'est fourni, affiche le domaine et le nom d'utilisateur en cours d'usage.\n\
Affiche les informations sur l'utilisateur, les groupes et les privilèges pour l'utilisateur actuellement connecté.\n\
Si aucun argument n'est fourni, affiche le domaine et le nom d'utilisateur en cours d'usage.\n\
\n\
Les formats de sortie disponibles pour l'option '/fo' sont 'csv', 'list' et 'table'.\n\
Utilisez '/nh' pour cacher les entêtes. Par défaut, les données sont affichées dans un tableau.\n\
Les formats de sortie disponibles pour l'option '/fo' sont 'csv', 'list' et 'table'.\n\
Utilisez '/nh' pour cacher les entêtes. Par défaut, les données sont affichées dans un tableau.\n\
\n\
SYNTAX:\n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Format>] [/nh] \n\
whoami /all [/fo <Format>] [/nh] \n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <Format>] [/nh] \n\
whoami /all [/fo <Format>] [/nh] \n\
\n\
EXAMPLES: \n\
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
END
@@ -40,19 +40,19 @@ BEGIN
IDS_ERROR_INVALIDARG "ОШИБКА: Неправильный параметр или аргумент - '%s'.\nВведите ""WHOAMI /?"" для получения справки по использованию.\n"
IDS_ERROR_NH_LIST "ОШИБКА: Параметр /NH нельзя использовать с форматом LIST.\nВведите ""WHOAMI /?"" для получения справки по использованию.\n"
IDS_HELP "Описание:\n\
Отображает информацию об пользователе, группе и привилегиях для локально вошедших пользователей.\n\
Если не указано аргументов, то отображает текущий домен и текущего пользователя (домен/пользователь).\n\
Отображает информацию об пользователе, группе и привилегиях для локально вошедших пользователей.\n\
Если не указано аргументов, то отображает текущий домен и текущего пользователя (домен/пользователь).\n\
\n\
Доступные форматы для параметра '/fo' - 'csv', 'list' и 'table'.\n\
Используйте '/nh' чтобы скрыть заголовки. По умолчанию данные отображаются в таблице.\n\
Доступные форматы для параметра '/fo' - 'csv', 'list' и 'table'.\n\
Используйте '/nh' чтобы скрыть заголовки. По умолчанию данные отображаются в таблице.\n\
\n\
Синтаксис:\n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <формат>] [/nh] \n\
whoami /all [/fo <формат>] [/nh] \n\
whoami [/upn | /fqdn | /logonid] \n\
whoami {[/user] [/groups] [/priv]} [/fo <формат>] [/nh] \n\
whoami /all [/fo <формат>] [/nh] \n\
\n\
Примеры:\n\
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
whoami /groups /priv /nh /fo csv \n\
whoami /logonid \n\
whoami \n"
END
@@ -15,6 +15,61 @@
#include "resource.h"
/* Unicode (W) to ANSI OEM wrapper function, as console and Unicode don't mix well, sigh */
static void WhoamiOemConversion_printf(const WCHAR *lpSourceFormatW, ...)
{
CHAR *lpBufferA = NULL;
WCHAR *lpBufferW = NULL;
UINT Size;
va_list Args;
/* first let's find out the final output'ed length of the wprintf routine */
va_start(Args, lpSourceFormatW);
Size = _vscwprintf(lpSourceFormatW, Args);
va_end(Args);
/* allocate a proportional memory chunk taking into account the char width */
lpBufferW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (Size + 1) * sizeof(WCHAR));
if (!lpBufferW)
return;
/* do wprintf to this newly allocated buffer of ours */
va_start(Args, lpSourceFormatW);
_vsnwprintf(lpBufferW, Size, lpSourceFormatW, Args);
va_end(Args);
/* allocate a similarly sized buffer for the ANSI/OEM version of our string */
lpBufferA = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (Size + 1) * sizeof(CHAR));
if (!lpBufferA)
{
HeapFree(GetProcessHeap(), 0, lpBufferW);
return;
}
/* convert our Unicode/Wide char string into a proper ANSI/OEM
string that our console may understand, at least in theory */
CharToOemBuffW(lpBufferW,
lpBufferA,
Size);
/* print the converted OEM string into the console's output and call it a day */
printf("%s", lpBufferA);
/* clean everything up */
HeapFree(GetProcessHeap(), 0, lpBufferW);
HeapFree(GetProcessHeap(), 0, lpBufferA);
}
#define wprintf WhoamiOemConversion_printf
BOOL NoHeader = FALSE;
UINT NoHeaderArgCount = 0;
UINT PrintFormatArgCount = 0;
@@ -139,7 +194,8 @@ void WhoamiPrintHeader(int HeaderId)
while (Length--)
wprintf(L"-");
_putws(L"\n");
/* _putws seems to be broken in ReactOS' CRT ??? */
wprintf(L"\n\n");
}
typedef struct
@@ -620,21 +676,27 @@ int WhoamiPriv(void)
WhoamiSetTableDyn(PrivTable, PrivName, dwIndex + 1, 0);
ret = LookupPrivilegeDisplayNameW(NULL, PrivName, NULL, &DispNameSize, &dwResult);
if (!ret || GetLastError() == ERROR_NO_SUCH_PRIVILEGE)
/* try to grab the size of the string, also, beware, as this call is
unimplemented in ReactOS/Wine at the moment */
LookupPrivilegeDisplayNameW(NULL, PrivName, NULL, &DispNameSize, &dwResult);
DispName = HeapAlloc(GetProcessHeap(), 0, ++DispNameSize * sizeof(WCHAR));
ret = LookupPrivilegeDisplayNameW(NULL, PrivName, DispName, &DispNameSize, &dwResult);
if (ret && DispName)
{
DispName = HeapAlloc(GetProcessHeap(), 0, ++DispNameSize * sizeof(WCHAR));
LookupPrivilegeDisplayNameW(NULL, PrivName, DispName, &DispNameSize, &dwResult);
//wprintf(L"DispName: %d %x '%s'\n", DispNameSize, GetLastError(), DispName);
// wprintf(L"DispName: %d %x '%s'\n", DispNameSize, GetLastError(), DispName);
WhoamiSetTableDyn(PrivTable, DispName, dwIndex + 1, 1);
}
else
{
WhoamiSetTable(PrivTable, WhoamiLoadRcString(IDS_UNKNOWN_DESCRIPTION), dwIndex + 1, 1);
if (DispName != NULL)
WhoamiFree(DispName);
}
if (pPrivInfo->Privileges[dwIndex].Attributes & SE_PRIVILEGE_ENABLED)