Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: paroxsitic on Aug 5th, 2011  |  syntax: C#  |  size: 22.88 KB  |  hits: 140  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1.     using System;
  2.     using System.Collections.Generic;
  3.     using System.Linq;
  4.     using System.Text;
  5.     using System.Security.Permissions;
  6.     using Microsoft.Win32;
  7.     using System.Runtime.InteropServices;
  8.     using System.Diagnostics;
  9.     using System.Collections;
  10.     using System.Threading;
  11.     using System.Security.AccessControl;
  12.     using System.Security.Principal;
  13.     using Microsoft.Win32.SafeHandles;
  14.     using System.ComponentModel;
  15.     using System;
  16.     using System.Collections.Generic;
  17.     using System.Runtime.InteropServices;
  18.     using System.Diagnostics;
  19.     using System.Text;
  20.     using System.Threading;
  21.    
  22.    
  23.     namespace EnumerateMutexACL
  24.     {
  25.    
  26.             class Win32API {
  27.                 [DllImport("ntdll.dll")]
  28.                 public static extern int NtQueryObject (IntPtr ObjectHandle, int
  29.                     ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength,
  30.                     ref int returnLength);
  31.    
  32.                 [DllImport("kernel32.dll", SetLastError = true)]
  33.                 public static extern uint QueryDosDevice (string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
  34.    
  35.                 [DllImport("ntdll.dll")]
  36.                 public static extern uint NtQuerySystemInformation (int
  37.                     SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength,
  38.                     ref int returnLength);
  39.    
  40.                 [DllImport("kernel32.dll")]
  41.                 public static extern IntPtr OpenProcess (ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
  42.                 [DllImport("kernel32.dll")]
  43.                 public static extern int CloseHandle (IntPtr hObject);
  44.                 [DllImport("kernel32.dll", SetLastError = true)]
  45.                 [return: MarshalAs(UnmanagedType.Bool)]
  46.                 public static extern bool DuplicateHandle (IntPtr hSourceProcessHandle,
  47.                    ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle,
  48.                    uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
  49.                 [DllImport("kernel32.dll")]
  50.                 public static extern IntPtr GetCurrentProcess ();
  51.    
  52.                 public enum ObjectInformationClass : int {
  53.                     ObjectBasicInformation = 0,
  54.                     ObjectNameInformation = 1,
  55.                     ObjectTypeInformation = 2,
  56.                     ObjectAllTypesInformation = 3,
  57.                     ObjectHandleInformation = 4
  58.                 }
  59.    
  60.                 [Flags]
  61.                 public enum ProcessAccessFlags : uint {
  62.                     All = 0x001F0FFF,
  63.                     Terminate = 0x00000001,
  64.                     CreateThread = 0x00000002,
  65.                     VMOperation = 0x00000008,
  66.                     VMRead = 0x00000010,
  67.                     VMWrite = 0x00000020,
  68.                     DupHandle = 0x00000040,
  69.                     SetInformation = 0x00000200,
  70.                     QueryInformation = 0x00000400,
  71.                     Synchronize = 0x00100000
  72.                 }
  73.    
  74.                 [StructLayout(LayoutKind.Sequential)]
  75.                 public struct OBJECT_BASIC_INFORMATION { // Information Class 0
  76.                     public int Attributes;
  77.                     public int GrantedAccess;
  78.                     public int HandleCount;
  79.                     public int PointerCount;
  80.                     public int PagedPoolUsage;
  81.                     public int NonPagedPoolUsage;
  82.                     public int Reserved1;
  83.                     public int Reserved2;
  84.                     public int Reserved3;
  85.                     public int NameInformationLength;
  86.                     public int TypeInformationLength;
  87.                     public int SecurityDescriptorLength;
  88.                     public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
  89.                 }
  90.    
  91.                 [StructLayout(LayoutKind.Sequential)]
  92.                 public struct OBJECT_TYPE_INFORMATION { // Information Class 2
  93.                     public UNICODE_STRING Name;
  94.                     public int ObjectCount;
  95.                     public int HandleCount;
  96.                     public int Reserved1;
  97.                     public int Reserved2;
  98.                     public int Reserved3;
  99.                     public int Reserved4;
  100.                     public int PeakObjectCount;
  101.                     public int PeakHandleCount;
  102.                     public int Reserved5;
  103.                     public int Reserved6;
  104.                     public int Reserved7;
  105.                     public int Reserved8;
  106.                     public int InvalidAttributes;
  107.                     public GENERIC_MAPPING GenericMapping;
  108.                     public int ValidAccess;
  109.                     public byte Unknown;
  110.                     public byte MaintainHandleDatabase;
  111.                     public int PoolType;
  112.                     public int PagedPoolUsage;
  113.                     public int NonPagedPoolUsage;
  114.                 }
  115.    
  116.                 [StructLayout(LayoutKind.Sequential)]
  117.                 public struct OBJECT_NAME_INFORMATION { // Information Class 1
  118.                     public UNICODE_STRING Name;
  119.                 }
  120.    
  121.                 [StructLayout(LayoutKind.Sequential, Pack = 1)]
  122.                 public struct UNICODE_STRING {
  123.                     public ushort Length;
  124.                     public ushort MaximumLength;
  125.                     public IntPtr Buffer;
  126.                 }
  127.    
  128.                 [StructLayout(LayoutKind.Sequential)]
  129.                 public struct GENERIC_MAPPING {
  130.                     public int GenericRead;
  131.                     public int GenericWrite;
  132.                     public int GenericExecute;
  133.                     public int GenericAll;
  134.                 }
  135.    
  136.                 [StructLayout(LayoutKind.Sequential, Pack = 1)]
  137.                 public struct SYSTEM_HANDLE_INFORMATION { // Information Class 16
  138.                     public int ProcessID;
  139.                     public byte ObjectTypeNumber;
  140.                     public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
  141.                     public ushort Handle;
  142.                     public int Object_Pointer;
  143.                     public UInt32 GrantedAccess;
  144.                 }
  145.    
  146.                 public const int MAX_PATH = 260;
  147.                 public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
  148.                 public const int DUPLICATE_SAME_ACCESS = 0x2;
  149.             }
  150.        
  151.        
  152.         class Token
  153.         {
  154.    
  155.    
  156.             [DllImport("advapi32.dll", SetLastError = true)]
  157.             [return: MarshalAs(UnmanagedType.Bool)]
  158.             static extern bool OpenProcessToken(IntPtr ProcessHandle,
  159.                 UInt32 DesiredAccess, out IntPtr TokenHandle);
  160.    
  161.             private static uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
  162.             private static uint STANDARD_RIGHTS_READ = 0x00020000;
  163.             private static uint TOKEN_ASSIGN_PRIMARY = 0x0001;
  164.             private static uint TOKEN_DUPLICATE = 0x0002;
  165.             private static uint TOKEN_IMPERSONATE = 0x0004;
  166.             private static uint TOKEN_QUERY = 0x0008;
  167.             private static uint TOKEN_QUERY_SOURCE = 0x0010;
  168.             private static uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
  169.             private static uint TOKEN_ADJUST_GROUPS = 0x0040;
  170.             private static uint TOKEN_ADJUST_DEFAULT = 0x0080;
  171.             private static uint TOKEN_ADJUST_SESSIONID = 0x0100;
  172.             private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
  173.             private static uint TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
  174.                 TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
  175.                 TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
  176.                 TOKEN_ADJUST_SESSIONID);
  177.    
  178.             [DllImport("kernel32.dll", SetLastError = true)]
  179.             static extern IntPtr GetCurrentProcess();
  180.    
  181.             [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  182.             [return: MarshalAs(UnmanagedType.Bool)]
  183.             static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
  184.                 out LUID lpLuid);
  185.    
  186.             public const string SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege";
  187.             public const string SE_AUDIT_NAME = "SeAuditPrivilege";
  188.             public const string SE_BACKUP_NAME = "SeBackupPrivilege";
  189.             public const string SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege";
  190.             public const string SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege";
  191.             public const string SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege";
  192.             public const string SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege";
  193.             public const string SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege";
  194.             public const string SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege";
  195.             public const string SE_DEBUG_NAME = "SeDebugPrivilege";
  196.             public const string SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege";
  197.             public const string SE_IMPERSONATE_NAME = "SeImpersonatePrivilege";
  198.             public const string SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege";
  199.             public const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
  200.             public const string SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege";
  201.             public const string SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege";
  202.             public const string SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege";
  203.             public const string SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege";
  204.             public const string SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege";
  205.             public const string SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege";
  206.             public const string SE_RELABEL_NAME = "SeRelabelPrivilege";
  207.             public const string SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege";
  208.             public const string SE_RESTORE_NAME = "SeRestorePrivilege";
  209.             public const string SE_SECURITY_NAME = "SeSecurityPrivilege";
  210.             public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
  211.             public const string SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege";
  212.             public const string SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege";
  213.             public const string SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege";
  214.             public const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
  215.             public const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
  216.             public const string SE_TCB_NAME = "SeTcbPrivilege";
  217.             public const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";
  218.             public const string SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege";
  219.             public const string SE_UNDOCK_NAME = "SeUndockPrivilege";
  220.             public const string SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege";
  221.    
  222.             [StructLayout(LayoutKind.Sequential)]
  223.             public struct LUID
  224.             {
  225.                 public UInt32 LowPart;
  226.                 public Int32 HighPart;
  227.             }
  228.    
  229.             public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
  230.             public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
  231.             public const UInt32 SE_PRIVILEGE_REMOVED = 0x00000004;
  232.             public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000;
  233.    
  234.             [StructLayout(LayoutKind.Sequential)]
  235.             public struct TOKEN_PRIVILEGES
  236.             {
  237.                 public UInt32 PrivilegeCount;
  238.                 public LUID Luid;
  239.                 public UInt32 Attributes;
  240.             }
  241.    
  242.             [StructLayout(LayoutKind.Sequential)]
  243.             public struct LUID_AND_ATTRIBUTES
  244.             {
  245.                 public LUID Luid;
  246.                 public UInt32 Attributes;
  247.             }
  248.    
  249.             // Use this signature if you do not want the previous state
  250.             [DllImport("advapi32.dll", SetLastError = true)]
  251.             [return: MarshalAs(UnmanagedType.Bool)]
  252.             static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
  253.                [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
  254.                ref TOKEN_PRIVILEGES NewState,
  255.                UInt32 Zero,
  256.                IntPtr Null1,
  257.                IntPtr Null2);
  258.    
  259.    
  260.             public static IntPtr GetToken(IntPtr hProcess)
  261.             {
  262.    
  263.                 IntPtr hToken;
  264.                 LUID luidSEDebugNameValue;
  265.                 TOKEN_PRIVILEGES tkpPrivileges;
  266.    
  267.                 if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
  268.                 {
  269.                     Console.WriteLine("OpenProcessToken() failed, error = {0} . SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
  270.                     return IntPtr.Zero;
  271.                 }
  272.                 else
  273.                 {
  274.                     Console.WriteLine("OpenProcessToken() successfully");
  275.                 }
  276.    
  277.                 if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out luidSEDebugNameValue))
  278.                 {
  279.                     Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
  280.                     Win.CloseHandle(hToken);
  281.                     return IntPtr.Zero;
  282.                 }
  283.                 else
  284.                 {
  285.                     Console.WriteLine("LookupPrivilegeValue() successfully");
  286.                 }
  287.    
  288.                 tkpPrivileges.PrivilegeCount = 1;
  289.                 tkpPrivileges.Luid = luidSEDebugNameValue;
  290.                 tkpPrivileges.Attributes = SE_PRIVILEGE_ENABLED;
  291.    
  292.                 if (!AdjustTokenPrivileges(hToken, false, ref tkpPrivileges, 0, IntPtr.Zero, IntPtr.Zero))
  293.                 {
  294.                     Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
  295.                     return IntPtr.Zero;
  296.                 }
  297.                 else
  298.                 {
  299.                     Console.WriteLine("SeDebugPrivilege is now available");
  300.                     return hToken;
  301.                 }
  302.             }
  303.    
  304.         }
  305.         class Win
  306.         {
  307.    
  308.    
  309.             [DllImport("kernel32.dll", SetLastError = true)]
  310.             public static extern IntPtr OpenMutex(uint dwDesiredAccess, bool bInheritHandle, string lpName);
  311.    
  312.    
  313.             [DllImport("kernel32.dll", SetLastError = true)]
  314.             public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName);
  315.    
  316.    
  317.             [DllImport("kernel32.dll", SetLastError = true)]
  318.             [return: MarshalAs(UnmanagedType.Bool)]
  319.             public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
  320.                IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle,
  321.                uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
  322.    
  323.             [DllImport("kernel32.dll", SetLastError = true)]
  324.             [return: MarshalAs(UnmanagedType.Bool)]
  325.             public static extern bool CloseHandle(IntPtr hObject);
  326.    
  327.         }
  328.    
  329.         class Program
  330.         {
  331.             static void testMutex(string mutexName)
  332.             {
  333.    
  334.                 Mutex m = null;
  335.                 bool doesNotExist = false;
  336.                 bool unauthorized = false;
  337.    
  338.                 // Attempt to open the named mutex.
  339.                 try
  340.                 {
  341.                     m = Mutex.OpenExisting(mutexName, MutexRights.FullControl);
  342.                 }
  343.                 catch (WaitHandleCannotBeOpenedException)
  344.                 {
  345.                     Console.WriteLine("Mutex does not exist.");
  346.                     doesNotExist = true;
  347.                 }
  348.                 catch (UnauthorizedAccessException ex)
  349.                 {
  350.                     Console.WriteLine("Unauthorized access: {0}", ex.Message);
  351.                     unauthorized = true;
  352.                 }
  353.    
  354.                  if (unauthorized)
  355.                 {
  356.                     // Open the mutex to read and change the access control
  357.                     // security. The access control security defined above
  358.                     // allows the current user to do this.
  359.                     //
  360.                     try
  361.                     {
  362.                         m = Mutex.OpenExisting(mutexName,
  363.                             MutexRights.ReadPermissions | MutexRights.ChangePermissions);
  364.    
  365.                         // Get the current ACL. This requires
  366.                         // MutexRights.ReadPermissions.
  367.                         MutexSecurity mSec = m.GetAccessControl();
  368.    
  369.                         string user = Environment.UserDomainName + "\\"
  370.                             + Environment.UserName;
  371.    
  372.                         // First, the rule that denied the current user
  373.                         // the right to enter and release the mutex must
  374.                         // be removed.
  375.                         MutexAccessRule rule = new MutexAccessRule(user,
  376.                              MutexRights.Synchronize | MutexRights.Modify,
  377.                              AccessControlType.Deny);
  378.                         mSec.RemoveAccessRule(rule);
  379.    
  380.                         // Now grant the user the correct rights.
  381.                         //
  382.                         rule = new MutexAccessRule(user,
  383.                             MutexRights.Synchronize | MutexRights.Modify,
  384.                             AccessControlType.Allow);
  385.                         mSec.AddAccessRule(rule);
  386.    
  387.                         // Update the ACL. This requires
  388.                         // MutexRights.ChangePermissions.
  389.                         m.SetAccessControl(mSec);
  390.    
  391.                         Console.WriteLine("Updated mutex security.");
  392.    
  393.                         // Open the mutex with (MutexRights.Synchronize
  394.                         // | MutexRights.Modify), the rights required to
  395.                         // enter and release the mutex.
  396.                         //
  397.                         m = Mutex.OpenExisting(mutexName);
  398.    
  399.                     }
  400.                     catch (UnauthorizedAccessException ex)
  401.                     {
  402.                         Console.WriteLine("Unable to change permissions: {0}",
  403.                             ex.Message);
  404.                         return;
  405.                     }
  406.    
  407.                 }
  408.    
  409.                 return;
  410.             }
  411.    
  412.             private static void parseMutex(string name)
  413.             {
  414.                 Mutex m;
  415.                 string mutexName = name;
  416.    
  417.                 try
  418.                 {
  419.                     m = Mutex.OpenExisting(mutexName);
  420.                     MutexSecurity mSec = m.GetAccessControl();
  421.                     Console.WriteLine(mSec.ToString());
  422.                 }
  423.                 catch (WaitHandleCannotBeOpenedException)
  424.                 {
  425.                     Console.WriteLine("Mutex does not exist.");
  426.    
  427.                 }
  428.                 catch (UnauthorizedAccessException ex)
  429.                 {
  430.                     Console.WriteLine("Unauthorized access: {0}", ex.Message);
  431.                     try
  432.                     {
  433.                         m = Mutex.OpenExisting(mutexName, MutexRights.FullControl);
  434.                         MutexSecurity mSec = m.GetAccessControl();
  435.                         ShowSecurity(mSec);
  436.                     }
  437.                     catch (Exception e)
  438.                     {
  439.                         Console.WriteLine("*******Unauthorized access: {0}", ex.Message);
  440.                     }
  441.    
  442.                 }
  443.             }
  444.             private static void ShowSecurity(MutexSecurity security)
  445.             {
  446.                 Console.WriteLine("\r\nAccess rules:\r\n");
  447.    
  448.                 foreach (MutexAccessRule ar in
  449.                     security.GetAccessRules(true, true, typeof(NTAccount)))
  450.                 {
  451.                     Console.WriteLine("        User: {0}", ar.IdentityReference);
  452.                     Console.WriteLine("        Type: {0}", ar.AccessControlType);
  453.                     Console.WriteLine("      Rights: {0}", ar.MutexRights);
  454.                     Console.WriteLine();
  455.                 }
  456.             }
  457.    
  458.             static void Main(string[] args)
  459.             {
  460.    
  461.                 IntPtr p, pp, ppp, pppp, hToken;
  462.                 string mutexname = "MSCTF.Asm.MutexDefault1";
  463.                 const uint DUPLICATE_CLOSE_SOURCE = 0x00000001;
  464.                 const UInt32 MUTEX_ALL_ACCESS = 0x1F0001;
  465.    
  466.                 testMutex(mutexname);
  467.                 parseMutex(mutexname);
  468.    
  469.                 p = Process.GetProcessesByName("calc")[0].Handle;
  470.                 hToken = Token.GetToken(p);
  471.    
  472.                
  473.                 pp = Win.CreateMutex(IntPtr.Zero, false, mutexname);
  474.                 if (Marshal.GetLastWin32Error() == 183)
  475.                     Console.WriteLine("CreateMutex() Found mutex {0} already existing, using handle {1}", mutexname, pp);
  476.                 else if (Marshal.GetLastWin32Error() == 0)
  477.                     Console.WriteLine("CreateMutex() did not find mutex {0}, creating new mutex: handle {1}", mutexname, pp);
  478.                 else
  479.                     Console.WriteLine("CreateMutex() failed, error = {0}", Marshal.GetLastWin32Error());
  480.                
  481.                
  482.                 pp = Win.OpenMutex(MUTEX_ALL_ACCESS, false, mutexname);
  483.                 if (pp == IntPtr.Zero)
  484.                     Console.WriteLine("OpenMutex() failed, error = {0}", Marshal.GetLastWin32Error());
  485.                 else
  486.                     Console.WriteLine("OpenMutex() Found mutex {0}, using handle {1}", mutexname, pp);
  487.    
  488.                 ppp = Process.GetCurrentProcess().Handle;
  489.                 pppp = IntPtr.Zero; //Process.GetProcessesByName("calc")[0].Handle;
  490.    
  491.                 if (!Win.DuplicateHandle(p, pp, ppp, out pppp, MUTEX_ALL_ACCESS, false, DUPLICATE_CLOSE_SOURCE))
  492.                     Console.WriteLine("DuplicateHandle() failed, error = {0}", Marshal.GetLastWin32Error());
  493.    
  494.    
  495.                 if (Win.OpenMutex(MUTEX_ALL_ACCESS, false, mutexname) == IntPtr.Zero)
  496.                     Console.WriteLine("OpenMutex() failed, error = {0} -- YOU WIN", Marshal.GetLastWin32Error());
  497.                 else
  498.                     Console.WriteLine("OpenMutex() Found mutex {0}, using handle {1} -- YOU FAILED", mutexname, pp);
  499.    
  500.                 Win.CloseHandle(hToken);
  501.                 Win.CloseHandle(pppp);
  502.                 Console.Read();
  503.                
  504.                 return;
  505.             }
  506.         }
  507.     }