- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试检索与 C# 中的 token 关联的权限及其当前状态,但我不知道如何调整返回的 LUID_AND_ATTRIBUTES
数组的大小以适应元素的实际数量。
来自 MSDN
When MarshalAsAttribute.Value is set to ByValArray, the SizeConst must be set to indicate the number of elements in the array.
在调用 GetTokenInformation
后,我能够查看 TOKEN_PRIVILEGES.PrivilegeCount
属性,并看到我正在使用的 token 具有 35 个权限中列出的 24 个权限Privilege Constants引用页。更改 SizeConst = 24
将使我能够看到所有这些,而不仅仅是第一个(我最初根据 PInvoke 中的用法示例设置了 SizeConst = 1
)
有没有办法在创建传入数组时指定传入数组的深度,或者我是否需要在编写代码之前知道将有多少权限?
[DllImport("advapi32.dll", SetLastError = true)]
protected static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, int TokenInformationLength, ref int ReturnLength);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)][return: MarshalAs(UnmanagedType.Bool)]
protected static extern bool LookupPrivilegeName(string lpSystemName, IntPtr lpLuid,System.Text.StringBuilder lpName, ref int cchName);
protected struct TOKEN_PRIVILEGES {
public UInt32 PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public LUID_AND_ATTRIBUTES[] Privileges;
}//TOKEN_PRIVILEGES
[StructLayout(LayoutKind.Sequential)]
protected struct LUID_AND_ATTRIBUTES {
public LUID Luid;
public UInt32 Attributes;
}//LUID_AND_ATTRIBUTES
[StructLayout(LayoutKind.Sequential)]
protected struct LUID {
public uint LowPart;
public int HighPart;
}//LUID
int TokenInfLength = 0;
IntPtr ThisHandle = WindowsIdentity.GetCurrent().Token;
GetTokenInformation(ThisHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, TokenInfLength, ref TokenInfLength); //Get the TokenInformation length (returns false)
IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength);
if(GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenPrivileges, TokenInformation, TokenInfLength, ref TokenInfLength)){
TOKEN_PRIVILEGES ThisPrivilegeSet = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_PRIVILEGES));
//ThisPrivilegeSet now holds all of the LUID's i need to check out
foreach(LUID_AND_ATTRIBUTES laa in ThisPrivilegeSet.Privileges){ //ThisPrivilegeSet.Privileges is only as deep as SizeConst will allow
System.Text.StringBuilder StrBuilder = new System.Text.StringBuilder();
int LuidNameLen = 0;
IntPtr LuidPointer = Marshal.AllocHGlobal(Marshal.SizeOf(laa.Luid));
Marshal.StructureToPtr(laa.Luid, LuidPointer, true);
LookupPrivilegeName(null, LuidPointer, null, ref LuidNameLen); //Get the PrivilageName length (returns false)
StrBuilder.EnsureCapacity(LuidNameLen + 1);
if(LookupPrivilegeName(null, LuidPointer, StrBuilder, ref LuidNameLen)){ //StrBuilder gets the name this time
Console.WriteLine("[{0}] : {1}", laa.Attributes.ToString(), StrBuilder.ToString());
}//end if
Marshal.FreeHGlobal(LuidPointer);
}//next
}//end if
这是我的第一篇文章,如果我做错了,我深表歉意,TIA 寻求帮助
最佳答案
我想跟进这个问题,因为我通过 VVS 提供的链接学到了一些东西。
如果您像我一样从未学习或使用过必须直接访问内存的编程语言,您可能也会发现这很有趣(顺便说一句,我已将 SwDevman81 的答案标记为正确答案,因为它运行良好)。
在 VVS 提供的博文中,作者谈到使用调用返回的指针的值(内存地址)+ 返回对象的大小来编码 block 中返回的数据,以动态检索可变数量的对象。在这种情况下以及博客文章中概述的情况下,我们受益于返回的第一个值包含以下数组中的元素数,我们还有一个从函数返回的整数告诉我们返回的结构有多大也可以用于检查我们是否已经到达结构的末尾,如果我们没有一个值告诉我们元素的数量的话。
我为任何对如何将上述博文应用于此场景感兴趣的人提供以下代码示例。
代码示例:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace MarshallingExample {
class Program {
protected struct TOKEN_PRIVILEGES {
public UInt32 PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public LUID_AND_ATTRIBUTES[] Privileges;
}
[StructLayout(LayoutKind.Sequential)]
protected struct LUID_AND_ATTRIBUTES {
public LUID Luid;
public UInt32 Attributes;
}
[StructLayout(LayoutKind.Sequential)]
protected struct LUID {
public uint LowPart;
public int HighPart;
}
//This enum was huge, I cut it down to save space
protected enum TOKEN_INFORMATION_CLASS {
/// <summary>
/// The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.
/// </summary>
TokenPrivileges = 3
}
[DllImport("advapi32.dll", SetLastError = true)]
protected static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, int TokenInformationLength, ref int ReturnLength);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool LookupPrivilegeName(string lpSystemName, IntPtr lpLuid, System.Text.StringBuilder lpName, ref int cchName);
static void Main(string[] args) {
//Check and print the privileges this token has
CheckPrivileges(WindowsIdentity.GetCurrent().Token);
}
//test function to output privileges for an account
private static bool CheckPrivileges(IntPtr thisHandle) {
int iTokenInfLength = 0; //holds the length of the TOKEN_PRIVILEGES structure that will be returned by GetTokenInformation
//First call to GetTokenInformation returns the length of the structure that will be returned on the next call
GetTokenInformation(thisHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, iTokenInfLength, ref iTokenInfLength);
//Allocate a block of memory large enough to hold the expected structure
IntPtr ipTokenInformation = Marshal.AllocHGlobal(iTokenInfLength);
//ipTokenInformation holds the starting location readable as an integer
//you can view the memory location using Ctrl-Alt-M,1 or Debug->Windows->Memory->Memory1 in Visual Studio
//and pasting the value of ipTokenInformation into the search box (it's still empty right now though)
if(GetTokenInformation(thisHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, ipTokenInformation, iTokenInfLength, ref iTokenInfLength)) {
//If GetTokenInformation doesn't return false then the structure should be sitting in the space reserved by ipTokenInformation
//at this point
//What was returned is a structure of type TOKEN_PRIVILEGES which has two values, a UInt32 followed by an array
//of LUID_AND_ATTRIBUTES structures. Because we know what to expect and we know the order to expect it we can section
//off the memory into marshalled structures and do some math to figure out where to start our next marshal
uint uiPrivilegeCount = (uint)Marshal.PtrToStructure(ipTokenInformation, typeof(uint)); //Get the count
//lets create the structure we should have had in the first place
LUID_AND_ATTRIBUTES[] aLuidAa = new LUID_AND_ATTRIBUTES[uiPrivilegeCount]; //initialize an array to the right size
LUID_AND_ATTRIBUTES cLuidAa = new LUID_AND_ATTRIBUTES();
//ipPointer will hold our new location to read from by taking the last pointer plus the size of the last structure read
IntPtr ipPointer = new IntPtr(ipTokenInformation.ToInt32() + sizeof(uint)); //first laa pointer
cLuidAa = (LUID_AND_ATTRIBUTES)Marshal.PtrToStructure(ipPointer, typeof(LUID_AND_ATTRIBUTES)); //Read the memory location
aLuidAa[0] = cLuidAa; //Add it to the array
//After getting our first structure we can loop through the rest since they will all be the same
for(int i = 1; i < uiPrivilegeCount; ++i) {
ipPointer = new IntPtr(ipPointer.ToInt32() + Marshal.SizeOf(cLuidAa)); //Update the starting point in ipPointer
cLuidAa = (LUID_AND_ATTRIBUTES)Marshal.PtrToStructure(ipPointer, typeof(LUID_AND_ATTRIBUTES)); //Read the memory location
aLuidAa[i] = cLuidAa; //Add it to the array
}//next
TOKEN_PRIVILEGES cPrivilegeSet = new TOKEN_PRIVILEGES();
cPrivilegeSet.PrivilegeCount = uiPrivilegeCount;
cPrivilegeSet.Privileges = aLuidAa;
//now we have what we should have had to begin with
Console.WriteLine("Privilege Count: {0}", cPrivilegeSet.PrivilegeCount.ToString());
//This loops through the LUID_AND_ATTRIBUTES array and resolves the LUID names with a
//call to LookupPrivilegeName which requires us to first convert our managed structure into an unmanaged one
//so we get to see what it looks like to do it backwards
foreach(LUID_AND_ATTRIBUTES cLaa in cPrivilegeSet.Privileges) {
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int iLuidNameLen = 0; //Holds the length of structure we will be receiving LookupPrivilagename
IntPtr ipLuid = Marshal.AllocHGlobal(Marshal.SizeOf(cLaa.Luid)); //Allocate a block of memory large enough to hold the structure
Marshal.StructureToPtr(cLaa.Luid, ipLuid, true); //Write the structure into the reserved space in unmanaged memory
LookupPrivilegeName(null, ipLuid, null, ref iLuidNameLen); // call once to get the name length we will be receiving
sb.EnsureCapacity(iLuidNameLen + 1); //Make sure there is enough room for it
if(LookupPrivilegeName(null, ipLuid, sb, ref iLuidNameLen)) { // call again to get the name
Console.WriteLine("[{0}] : {1}", cLaa.Attributes.ToString(), sb.ToString());
}//end if
Marshal.FreeHGlobal(ipLuid); //Free up the reserved space in unmanaged memory (Should be done any time AllocHGlobal is used)
}//next
Marshal.FreeHGlobal(ipTokenInformation); //Free up the reserved space in unmanaged memory (Should be done any time AllocHGlobal is used)
}//end if GetTokenInformation
return true;
}//CheckPrivileges
}//Program
}//MarshallingExample
关于c# - 设置 GetTokenInformation 返回的 TOKEN_PRIVILEGES.LUID_AND_ATTRIBUTES 数组的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4349743/
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
在编码时,我问了自己这个问题: 这样更快吗: if(false) return true; else return false; 比这个? if(false) return true; return
如何在逻辑条件下进行“返回”? 在这样的情况下这会很有用 checkConfig() || return false; var iNeedThis=doSomething() || return fa
这是我的正则表达式 demo 如问题所述: 如果第一个数字是 1 则返回 1 但如果是 145 则返回 145 但如果是 133 则返回 133 样本数据a: K'8134567 K'81345678
在代码高尔夫问答部分查看谜题和答案时,我遇到了 this solution返回 1 的最长和最晦涩的方法 引用答案, int foo(void) { return! 0; } int bar(
我想在下面返回 JSON。 { "name": "jackie" } postman 给我错误。说明 Unexpected 'n' 这里是 Spring Boot 的新手。 1日龄。有没有正确的方法来
只要“is”返回 True,“==”不应该返回 True 吗? In [101]: np.NAN is np.nan is np.NaN Out[101]: True In [102]: np.NAN
我需要获取所有在 6 号或 7 号房间或根本不在任何房间的学生的详细信息。如果他们在其他房间,简单地说,我不希望有那个记录。 我的架构是: students(roll_no, name,class,.
我有一个表单,我将它发送到 php 以通过 ajax 插入到 mysql 数据库中。一切顺利,php 返回 "true" 值,但在 ajax 中它显示 false 消息。 在这里你可以查看php代码:
我在 Kotlin 中遇到了一个非常奇怪的无法解释的值比较问题,以下代码打印 假 data class Foo ( val a: Byte ) fun main() { val NUM
请注意,这并非特定于 Protractor。问题在于 Angular 2 的内置 Testability service Protractor 碰巧使用。 Protractor 调用 Testabil
在调试窗口中,以下表达式均返回 1。 Application.WorksheetFunction.CountA(Cells(4 + (i - 1) * rows_per_record, 28) & "
我在本地使用 jsonplaceholder ( http://jsonplaceholder.typicode.com/)。我正在通过 extjs rest 代理测试我的 GET 和 POST 调用
这是 Postman 为成功调用我的页面而提供的(修改后的)代码段。 var client = new RestClient("http://sub.example.com/wp-json/wp/v2
这个问题在这里已经有了答案: What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must
我想我对 C 命令行参数有点生疏。我查看了我的一些旧代码,但无论这个版本是什么,都会出现段错误。 运行方式是 ./foo -n num(其中 num 是用户在命令行中输入的数字) 但不知何故它不起作用
我已经编写了一个类来处理命名管道连接,如果我创建了一个实例,关闭它,然后尝试创建另一个实例,调用 CreateFile() 返回 INVALID_HANDLE_VALUE,并且 GetLastErro
即使 is_writable() 返回 true,我也无法写入文件。当然,该文件存在并且显然是可读的。这是代码: $file = "data"; echo file_get_contents($fil
下面代码中的变量 $response 为 NULL,尽管它应该是 SOAP 请求的值。 (潮汐列表)。当我调用 $client->__getLastResponse() 时,我从 SOAP 服务获得了
我一直在网上的不同论坛上搜索答案,但似乎没有与我的情况相符的... 我正在使用 Windows 7,VS2010。 我有一个使用定时器来调用任务栏刷新功能的应用程序。在该任务栏函数中包含对 LoadI
我是一名优秀的程序员,十分优秀!