NSIS/Contrib/UserInfo/UserInfo.c
wizou 752d7d239a Jim Park's Unicode NSIS merging - Step 1 : switch to TCHARs where relevant.
Compiler output is identical before & after this step

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/branches/wizou@6036 212acab6-be3b-0410-9dea-997c60f758d6
2010-03-24 17:22:56 +00:00

147 lines
4.4 KiB
C

// Unicode support by Jim Park -- 08/23/2007
#include <windows.h>
#include <nsis/pluginapi.h> // nsis plugin
typedef BOOL (WINAPI*CHECKTOKENMEMBERSHIP)(HANDLE TokenHandle,PSID SidToCheck,PBOOL IsMember);
CHECKTOKENMEMBERSHIP _CheckTokenMembership=NULL;
void __declspec(dllexport) GetName(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop)
{
EXDLL_INIT();
{
DWORD dwStringSize = g_stringsize;
stack_t *th;
if (!g_stacktop) return;
th = (stack_t*) GlobalAlloc(GPTR, sizeof(stack_t) + g_stringsize*sizeof(TCHAR));
GetUserName(th->text, &dwStringSize);
th->next = *g_stacktop;
*g_stacktop = th;
}
}
TCHAR* GetAccountTypeHelper(BOOL CheckTokenForGroupDeny)
{
TCHAR *group = NULL;
HANDLE hToken = NULL;
struct group
{
DWORD auth_id;
TCHAR *name;
};
struct group groups[] =
{
{DOMAIN_ALIAS_RID_USERS, _T("User")},
// every user belongs to the users group, hence users come before guests
{DOMAIN_ALIAS_RID_GUESTS, _T("Guest")},
{DOMAIN_ALIAS_RID_POWER_USERS, _T("Power")},
{DOMAIN_ALIAS_RID_ADMINS, _T("Admin")}
};
if (GetVersion() & 0x80000000) // Not NT
{
return _T("Admin");
}
// First we must open a handle to the access token for this thread.
if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken) ||
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = {SECURITY_NT_AUTHORITY};
TOKEN_GROUPS *ptg = NULL;
BOOL ValidTokenGroups = FALSE;
DWORD cbTokenGroups;
DWORD i, j;
if (CheckTokenForGroupDeny)
// GetUserName is in advapi32.dll so we can avoid Load/Freelibrary
_CheckTokenMembership=
(CHECKTOKENMEMBERSHIP) GetProcAddress(
GetModuleHandle(_T("ADVAPI32")), "CheckTokenMembership");
// Use "old school" membership check?
if (!CheckTokenForGroupDeny || _CheckTokenMembership == NULL)
{
// We must query the size of the group information associated with
// the token. Note that we expect a FALSE result from GetTokenInformation
// because we've given it a NULL buffer. On exit cbTokenGroups will tell
// the size of the group information.
if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &cbTokenGroups) &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
// Allocate buffer and ask for the group information again.
// This may fail if an administrator has added this account
// to an additional group between our first call to
// GetTokenInformation and this one.
if ((ptg = GlobalAlloc(GPTR, cbTokenGroups)) &&
GetTokenInformation(hToken, TokenGroups, ptg, cbTokenGroups, &cbTokenGroups))
{
ValidTokenGroups=TRUE;
}
}
}
if (ValidTokenGroups || (CheckTokenForGroupDeny && _CheckTokenMembership))
{
PSID psid;
for (i = 0; i < sizeof(groups)/sizeof(struct group); i++)
{
// Create a SID for the local group and then check if it exists in our token
if (AllocateAndInitializeSid(
&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
groups[i].auth_id, 0, 0, 0, 0, 0, 0,&psid))
{
BOOL IsMember = FALSE;
if (CheckTokenForGroupDeny && _CheckTokenMembership)
{
_CheckTokenMembership(0, psid, &IsMember);
}
else if (ValidTokenGroups)
{
for (j = 0; j < ptg->GroupCount; j++)
{
if (EqualSid(ptg->Groups[j].Sid, psid))
{
IsMember = TRUE;
}
}
}
if (IsMember) group=groups[i].name;
FreeSid(psid);
}
}
}
if (ptg)
GlobalFree(ptg);
CloseHandle(hToken);
return group;
}
return _T("");
}
void __declspec(dllexport) GetAccountType(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop)
{
EXDLL_INIT();
pushstring(GetAccountTypeHelper(TRUE));
}
void __declspec(dllexport) GetOriginalAccountType(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop)
{
EXDLL_INIT();
pushstring(GetAccountTypeHelper(FALSE));
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}