在 Windows 7 上模拟

Posted

技术标签:

【中文标题】在 Windows 7 上模拟【英文标题】:Impersonation on windows 7 【发布时间】:2013-07-15 15:31:51 【问题描述】:

我一直在开发一些通过本地域复制文件的应用程序。当我尝试使用 Windows XP 上的应用程序复制文件时,使用一个完全没有权限的帐户,该帐户完全可以模拟一个帐户,一切都完美地完成了。但是,当我在 Windows 7 上使用与上述相同的帐户时,应用程序在第一行返回“拒绝访问”

我在Impersonate msdn 上使用了相同的 sn-p 代码,但这是我的带有 fileSeeker 功能的代码:

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    // Test harness. 
    // If you incorporate this code into a DLL, be sure to demand FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]

    public impersonateSetting(string userName, string domainName, string password, string pathToSeek)
    
        SafeTokenHandle safeTokenHandle;
        try
        

            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token. 
            const int LOGON32_LOGON_INTERACTIVE = 2;

            // Call LogonUser to obtain a handle to an access token. 
            bool returnValue = LogonUser(userName, domainName, password,
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);

            Console.WriteLine("LogonUser called.");

            if (false == returnValue)
            
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : 0", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            
            using (safeTokenHandle)
            
                Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);

                // Check the identity.
                Console.WriteLine("Before impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
                // Use the token handle returned by LogonUser. 
                using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
                
                    using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
                    

                        // Check the identity.
                        Console.WriteLine("After impersonation: "
                            + WindowsIdentity.GetCurrent().Name);

                        fileRunner.fileSeeker(pathToSeek, true);

                    
                
                // Releasing the context object stops the impersonation 
                // Check the identity.
                Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
            
        
        catch (Exception ex)
        
            Console.WriteLine("Exception occurred. " + ex.Message);
        
    


public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid

    private SafeTokenHandle()
        : base(true)
    
    

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr handle);

    protected override bool ReleaseHandle()
    
        return CloseHandle(handle);
    

fileSeeker 函数:

    public static void fileSeeker(string paramFrom, bool copySub)
    
        DirectoryInfo dir = new DirectoryInfo(paramFrom);
        DirectoryInfo[] dirs = dir.GetDirectories();

        try
        
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            
                    string temppath = Path.Combine(paramFrom, file.Name);
                    try
                    
                        Console.WriteLine("Accessing: " + temppath);
                    
                    catch
                    
                        Console.WriteLine("Cant Access to " + temppath);
                    
            

            if (copySub)
            
                foreach (DirectoryInfo subdir in dirs)
                
                    string temppath = Path.Combine(paramFrom, subdir.Name);

                    fileSeeker(subdir.FullName, copySub);
                
            

        
        catch (Exception ex)
        
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        

    


感谢您的帮助!

【问题讨论】:

它到底在哪里失败了,第一行在这里DirectoryInfo dir = new DirectoryInfo(paramFrom); 还是在其他地方? 实际上它根本不会失败.. 从一个无权访问的会话访问文件,并模拟一个可以访问的帐户在win7上拒绝访问。但是,是的,它会拒绝访问这条线 【参考方案1】:

如果这里失败,FileInfo[] files = dir.GetFiles();,很可能是您模拟的帐户没有权限访问运行它的 Win7 计算机上的 dir 路径,请确保该帐户首先有权访问源路径,模拟代码好像没问题

【讨论】:

但通常用户无权访问此文件,但我希望他们能够使用管理员帐户将这些文件从计算机 A 复制到计算机 B,而无需他们知道其密码跨度> @Jean-PhilippeLépine 对,我的意思是,您模拟的帐户(“管理员帐户”)是否可能无法访问 dir 指向的任何路径? 实际上,使用管理员帐户,我们可以使用“\\computerName\C$\etc..”轻松访问这些文件夹和文件,但是当我尝试使用模拟与应用程序时我们得到一个拒绝访问,它只发生在 Windows 7 上。用户无权访问它们。

以上是关于在 Windows 7 上模拟的主要内容,如果未能解决你的问题,请参考以下文章

模拟器在 Windows 7 上非常慢

Windows Phone 7 模拟器无法运行

如何在模拟器上获取 Windows Phone 7 中的当前位置

虚拟机上的 Windows Phone 7 模拟器?

TextBox.TextChanged 事件在 Windows Phone 7 模拟器上触发两次

在 Windows Phone 7 中显示位置在模拟器中有效,但在真实手机上无效