├── .gitignore ├── LICENSE.txt ├── README.md ├── StartProcessAsUser.sln ├── StartProcessAsUser ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── StartProcessAsUser.csproj └── app.manifest ├── StartProcessLib ├── DesktopPermissionManager.cs ├── JobObject.cs ├── PInvoke │ ├── CloseHandle.cs │ ├── Constants.cs │ ├── CreateEnvironmentBlock.cs │ ├── CreateProcess.cs │ ├── DuplicateTokenEx.cs │ ├── Enums.cs │ ├── GetCurrentThreadId.cs │ ├── GetProcessWindowStation.cs │ ├── GetThreadDesktop.cs │ ├── JobObjectHandle.cs │ ├── JobObjectInfoClass.cs │ ├── JobObjectMethods.cs │ ├── JobObjectStructs.cs │ ├── LogonUser.cs │ ├── NativeMethods.cs │ ├── RevertToSelf.cs │ ├── SafeUserTokenHandle.cs │ ├── SecurityAttributes.cs │ └── Utils.cs ├── Properties │ └── AssemblyInfo.cs ├── StartProcessLib.csproj └── packages.config ├── StartProcessService ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── StartProcessService.csproj ├── WinService.cs └── packages.config ├── lib ├── AsproLock.dll ├── AsproLock.pdb └── AsproLock.xml └── licenses ├── asprosys.txt └── uhuru_software.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright [2013] [Luke Bakken] 2 | 3 | Please also refer to licenses/ for included software component licenses. 4 | 5 | ------------------------------------------------------------------------ 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | Apache License 20 | Version 2.0, January 2004 21 | http://www.apache.org/licenses/ 22 | 23 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 24 | 25 | 1. Definitions. 26 | 27 | "License" shall mean the terms and conditions for use, reproduction, 28 | and distribution as defined by Sections 1 through 9 of this document. 29 | 30 | "Licensor" shall mean the copyright owner or entity authorized by 31 | the copyright owner that is granting the License. 32 | 33 | "Legal Entity" shall mean the union of the acting entity and all 34 | other entities that control, are controlled by, or are under common 35 | control with that entity. For the purposes of this definition, 36 | "control" means (i) the power, direct or indirect, to cause the 37 | direction or management of such entity, whether by contract or 38 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 39 | outstanding shares, or (iii) beneficial ownership of such entity. 40 | 41 | "You" (or "Your") shall mean an individual or Legal Entity 42 | exercising permissions granted by this License. 43 | 44 | "Source" form shall mean the preferred form for making modifications, 45 | including but not limited to software source code, documentation 46 | source, and configuration files. 47 | 48 | "Object" form shall mean any form resulting from mechanical 49 | transformation or translation of a Source form, including but 50 | not limited to compiled object code, generated documentation, 51 | and conversions to other media types. 52 | 53 | "Work" shall mean the work of authorship, whether in Source or 54 | Object form, made available under the License, as indicated by a 55 | copyright notice that is included in or attached to the work 56 | (an example is provided in the Appendix below). 57 | 58 | "Derivative Works" shall mean any work, whether in Source or Object 59 | form, that is based on (or derived from) the Work and for which the 60 | editorial revisions, annotations, elaborations, or other modifications 61 | represent, as a whole, an original work of authorship. For the purposes 62 | of this License, Derivative Works shall not include works that remain 63 | separable from, or merely link (or bind by name) to the interfaces of, 64 | the Work and Derivative Works thereof. 65 | 66 | "Contribution" shall mean any work of authorship, including 67 | the original version of the Work and any modifications or additions 68 | to that Work or Derivative Works thereof, that is intentionally 69 | submitted to Licensor for inclusion in the Work by the copyright owner 70 | or by an individual or Legal Entity authorized to submit on behalf of 71 | the copyright owner. For the purposes of this definition, "submitted" 72 | means any form of electronic, verbal, or written communication sent 73 | to the Licensor or its representatives, including but not limited to 74 | communication on electronic mailing lists, source code control systems, 75 | and issue tracking systems that are managed by, or on behalf of, the 76 | Licensor for the purpose of discussing and improving the Work, but 77 | excluding communication that is conspicuously marked or otherwise 78 | designated in writing by the copyright owner as "Not a Contribution." 79 | 80 | "Contributor" shall mean Licensor and any individual or Legal Entity 81 | on behalf of whom a Contribution has been received by Licensor and 82 | subsequently incorporated within the Work. 83 | 84 | 2. Grant of Copyright License. Subject to the terms and conditions of 85 | this License, each Contributor hereby grants to You a perpetual, 86 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 87 | copyright license to reproduce, prepare Derivative Works of, 88 | publicly display, publicly perform, sublicense, and distribute the 89 | Work and such Derivative Works in Source or Object form. 90 | 91 | 3. Grant of Patent License. Subject to the terms and conditions of 92 | this License, each Contributor hereby grants to You a perpetual, 93 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 94 | (except as stated in this section) patent license to make, have made, 95 | use, offer to sell, sell, import, and otherwise transfer the Work, 96 | where such license applies only to those patent claims licensable 97 | by such Contributor that are necessarily infringed by their 98 | Contribution(s) alone or by combination of their Contribution(s) 99 | with the Work to which such Contribution(s) was submitted. If You 100 | institute patent litigation against any entity (including a 101 | cross-claim or counterclaim in a lawsuit) alleging that the Work 102 | or a Contribution incorporated within the Work constitutes direct 103 | or contributory patent infringement, then any patent licenses 104 | granted to You under this License for that Work shall terminate 105 | as of the date such litigation is filed. 106 | 107 | 4. Redistribution. You may reproduce and distribute copies of the 108 | Work or Derivative Works thereof in any medium, with or without 109 | modifications, and in Source or Object form, provided that You 110 | meet the following conditions: 111 | 112 | (a) You must give any other recipients of the Work or 113 | Derivative Works a copy of this License; and 114 | 115 | (b) You must cause any modified files to carry prominent notices 116 | stating that You changed the files; and 117 | 118 | (c) You must retain, in the Source form of any Derivative Works 119 | that You distribute, all copyright, patent, trademark, and 120 | attribution notices from the Source form of the Work, 121 | excluding those notices that do not pertain to any part of 122 | the Derivative Works; and 123 | 124 | (d) If the Work includes a "NOTICE" text file as part of its 125 | distribution, then any Derivative Works that You distribute must 126 | include a readable copy of the attribution notices contained 127 | within such NOTICE file, excluding those notices that do not 128 | pertain to any part of the Derivative Works, in at least one 129 | of the following places: within a NOTICE text file distributed 130 | as part of the Derivative Works; within the Source form or 131 | documentation, if provided along with the Derivative Works; or, 132 | within a display generated by the Derivative Works, if and 133 | wherever such third-party notices normally appear. The contents 134 | of the NOTICE file are for informational purposes only and 135 | do not modify the License. You may add Your own attribution 136 | notices within Derivative Works that You distribute, alongside 137 | or as an addendum to the NOTICE text from the Work, provided 138 | that such additional attribution notices cannot be construed 139 | as modifying the License. 140 | 141 | You may add Your own copyright statement to Your modifications and 142 | may provide additional or different license terms and conditions 143 | for use, reproduction, or distribution of Your modifications, or 144 | for any such Derivative Works as a whole, provided Your use, 145 | reproduction, and distribution of the Work otherwise complies with 146 | the conditions stated in this License. 147 | 148 | 5. Submission of Contributions. Unless You explicitly state otherwise, 149 | any Contribution intentionally submitted for inclusion in the Work 150 | by You to the Licensor shall be under the terms and conditions of 151 | this License, without any additional terms or conditions. 152 | Notwithstanding the above, nothing herein shall supersede or modify 153 | the terms of any separate license agreement you may have executed 154 | with Licensor regarding such Contributions. 155 | 156 | 6. Trademarks. This License does not grant permission to use the trade 157 | names, trademarks, service marks, or product names of the Licensor, 158 | except as required for reasonable and customary use in describing the 159 | origin of the Work and reproducing the content of the NOTICE file. 160 | 161 | 7. Disclaimer of Warranty. Unless required by applicable law or 162 | agreed to in writing, Licensor provides the Work (and each 163 | Contributor provides its Contributions) on an "AS IS" BASIS, 164 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 165 | implied, including, without limitation, any warranties or conditions 166 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 167 | PARTICULAR PURPOSE. You are solely responsible for determining the 168 | appropriateness of using or redistributing the Work and assume any 169 | risks associated with Your exercise of permissions under this License. 170 | 171 | 8. Limitation of Liability. In no event and under no legal theory, 172 | whether in tort (including negligence), contract, or otherwise, 173 | unless required by applicable law (such as deliberate and grossly 174 | negligent acts) or agreed to in writing, shall any Contributor be 175 | liable to You for damages, including any direct, indirect, special, 176 | incidental, or consequential damages of any character arising as a 177 | result of this License or out of the use or inability to use the 178 | Work (including but not limited to damages for loss of goodwill, 179 | work stoppage, computer failure or malfunction, or any and all 180 | other commercial damages or losses), even if such Contributor 181 | has been advised of the possibility of such damages. 182 | 183 | 9. Accepting Warranty or Additional Liability. While redistributing 184 | the Work or Derivative Works thereof, You may choose to offer, 185 | and charge a fee for, acceptance of support, warranty, indemnity, 186 | or other liability obligations and/or rights consistent with this 187 | License. However, in accepting such obligations, You may act only 188 | on Your own behalf and on Your sole responsibility, not on behalf 189 | of any other Contributor, and only if You agree to indemnify, 190 | defend, and hold each Contributor harmless for any liability 191 | incurred by, or claims asserted against, such Contributor by reason 192 | of your accepting any such warranty or additional liability. 193 | 194 | END OF TERMS AND CONDITIONS 195 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | windows-processes 2 | ================= 3 | 4 | C# code for starting processes. 5 | -------------------------------------------------------------------------------- /StartProcessAsUser.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartProcessAsUser", "StartProcessAsUser\StartProcessAsUser.csproj", "{6E2794EC-90F0-49AC-B80A-4CE091152499}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartProcessLib", "StartProcessLib\StartProcessLib.csproj", "{3324447D-2457-404A-A1D8-B739C5150D2D}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartProcessService", "StartProcessService\StartProcessService.csproj", "{8E1DF9CB-D053-4A2F-826D-FAE2BDBDC139}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {6E2794EC-90F0-49AC-B80A-4CE091152499}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {6E2794EC-90F0-49AC-B80A-4CE091152499}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {6E2794EC-90F0-49AC-B80A-4CE091152499}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {6E2794EC-90F0-49AC-B80A-4CE091152499}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {3324447D-2457-404A-A1D8-B739C5150D2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {3324447D-2457-404A-A1D8-B739C5150D2D}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {3324447D-2457-404A-A1D8-B739C5150D2D}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {3324447D-2457-404A-A1D8-B739C5150D2D}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {8E1DF9CB-D053-4A2F-826D-FAE2BDBDC139}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {8E1DF9CB-D053-4A2F-826D-FAE2BDBDC139}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {8E1DF9CB-D053-4A2F-826D-FAE2BDBDC139}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {8E1DF9CB-D053-4A2F-826D-FAE2BDBDC139}.Release|Any CPU.Build.0 = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /StartProcessAsUser/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /StartProcessAsUser/Program.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessAsUser 2 | { 3 | using System; 4 | using System.ComponentModel; 5 | using System.Security.AccessControl; 6 | using System.Text; 7 | using Asprosys.Security.AccessControl; 8 | using StartProcessLib; 9 | using StartProcessLib.PInvoke; 10 | 11 | // http://www.installsetupconfig.com/win32programming/windowstationsdesktops13_4.html 12 | // http://bytes.com/topic/net/answers/577257-impersonation-vs-job-api 13 | static class Program 14 | { 15 | const string workingDir = @"C:\tmp"; 16 | // create with 'net user test_user password /add' 17 | const string userName = "test_user"; 18 | const string password = "Pass@word1"; 19 | 20 | private static readonly DesktopPermissionManager permissionManager = new DesktopPermissionManager(userName); 21 | 22 | static void Main(string[] args) 23 | { 24 | try 25 | { 26 | permissionManager.AddDesktopPermission(); 27 | 28 | using (var jobObject = new JobObject("StartProcessAsUserJob")) 29 | { 30 | jobObject.KillProcessesOnJobClose = true; 31 | 32 | RunProcs: 33 | for (ushort i = 0; i < 1; ++i) 34 | { 35 | try 36 | { 37 | var p = DoCreateProcessAsUser(); 38 | // var p = DoCreateProcessWithLogon(); 39 | // jobObject.AddProcess(p.hProcess); 40 | } 41 | catch (Win32Exception ex) 42 | { 43 | Console.Error.WriteLine("ERROR: '{0}' Error code: '{1}' Native error code: '{2}'", ex.Message, ex.ErrorCode, ex.NativeErrorCode); 44 | } 45 | catch (Exception ex) 46 | { 47 | Console.Error.WriteLine("ERROR: '{0}'", ex.Message); 48 | } 49 | } 50 | Console.WriteLine("Type 'again' to create again, hit enter to exit..."); 51 | string cmd = Console.ReadLine().Trim().ToLowerInvariant(); 52 | if (cmd == "again") 53 | { 54 | goto RunProcs; 55 | } 56 | } 57 | } 58 | finally 59 | { 60 | permissionManager.RemoveDesktopPermission(); 61 | } 62 | } 63 | 64 | private static NativeMethods.ProcessInformation DoCreateProcessWithLogon() 65 | { 66 | var cmdLine = new StringBuilder(1024); 67 | // cmdLine.Append(@"powershell.exe -NoExit -Command ""dir env:"""); // Look at the environment 68 | cmdLine.Append(@"cmd.exe /k set"); // Look at the environment 69 | 70 | var createProcessFlags = NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE | 71 | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; 72 | /* 73 | NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW | 74 | NativeMethods.CreateProcessFlags.CREATE_BREAKAWAY_FROM_JOB | 75 | NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE; 76 | */ 77 | 78 | var startupInfo = new NativeMethods.StartupInfo(); 79 | 80 | NativeMethods.ProcessInformation pi; 81 | 82 | if (NativeMethods.CreateProcessWithLogon(userName, ".", password, 83 | NativeMethods.LogonFlags.LOGON_WITH_PROFILE, 84 | null, 85 | cmdLine, 86 | createProcessFlags, 87 | IntPtr.Zero, 88 | workingDir, 89 | startupInfo, 90 | out pi)) 91 | { 92 | Console.WriteLine("create-process-with-logon cmd: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); 93 | return pi; 94 | } 95 | else 96 | { 97 | throw new Win32Exception(); 98 | } 99 | } 100 | 101 | private static NativeMethods.ProcessInformation DoCreateProcessAsUser() 102 | { 103 | var startupInfo = new NativeMethods.StartupInfo(); 104 | 105 | string lpApplicationName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; 106 | // string lpApplicationName = @"C:\Windows\System32\cmd.exe"; 107 | 108 | var cmdLine = new StringBuilder(1024); 109 | // NB: /k will keep window open. Try running powershell from the window and you won't see any modules available. Weird. 110 | // This works, however: runas /user:test_user /noprofile /savecred "powershell -NoExit" 111 | // cmdLine.Append(@" /k set"); 112 | 113 | // Other commands to try: 114 | // cmdLine.Append(@" -NoExit -Command ""dir env:"""); // Look at the environment 115 | // cmdLine.Append(@"powershell.exe -InputFormat None -NoLogo -NoProfile -NonInteractive -Command ""echo 'START'; Start-Sleep -s 15; echo 'STOP'"""); 116 | // cmdLine.Append(@"cmd /c ping 127.0.0.1 -n 15 -w 1000"); // Useful for "sleep" 117 | cmdLine.Append(@" -InputFormat None -NoLogo -NoProfile -NonInteractive -Command ""Add-Content -Path C:\tmp\test.txt -Value FOO"""); 118 | 119 | // Create structs 120 | var saProcessAttributes = new NativeMethods.SecurityAttributes(); 121 | var saThreadAttributes = new NativeMethods.SecurityAttributes(); 122 | 123 | // Now create the process as the user 124 | NativeMethods.ProcessInformation pi; 125 | 126 | var createProcessFlags = 127 | NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW | 128 | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; 129 | // NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE; // Remove this to have a hidden window. Having this here allows you to see output 130 | 131 | IntPtr primaryToken = Utils.LogonAndGetPrimaryToken(userName, password); 132 | 133 | /* 134 | uint sessionId = 1; 135 | if (NativeMethods.SetTokenInformation(primaryToken, 136 | NativeMethods.TokenInformationClass.TokenSessionId, 137 | ref sessionId, (uint)Marshal.SizeOf(sessionId))) 138 | { 139 | */ 140 | if (NativeMethods.CreateProcessWithToken(primaryToken, NativeMethods.LogonFlags.LOGON_WITH_PROFILE, 141 | lpApplicationName, cmdLine.ToString(), createProcessFlags, IntPtr.Zero, workingDir, 142 | startupInfo, out pi)) 143 | { 144 | Console.WriteLine("create-process-with-token cmd: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); 145 | return pi; 146 | } 147 | else 148 | { 149 | throw new Win32Exception(); 150 | } 151 | /* 152 | } 153 | else 154 | { 155 | throw new Win32Exception(); 156 | } 157 | */ 158 | 159 | /* 160 | var profileInfo = new NativeMethods.ProfileInfo(); 161 | profileInfo.lpUserName = userName; 162 | 163 | if (NativeMethods.LoadUserProfile(primaryToken, profileInfo)) 164 | { 165 | IntPtr envBlock = IntPtr.Zero; 166 | if (NativeMethods.CreateEnvironmentBlock(out envBlock, primaryToken, false)) 167 | { 168 | // http://odetocode.com/blogs/scott/archive/2004/10/29/createprocessasuser.aspx 169 | if (NativeMethods.CreateProcessAsUser( 170 | primaryToken, 171 | lpApplicationName, 172 | cmdLine, // lpCommandLine 173 | saProcessAttributes, 174 | saThreadAttributes, 175 | false, // bInheritHandles 176 | createProcessFlags, 177 | envBlock, 178 | workingDir, 179 | startupInfo, 180 | out pi)) 181 | { 182 | Console.WriteLine("create-process-as-user cmd: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); 183 | return pi; 184 | } 185 | else 186 | { 187 | throw new Win32Exception(); 188 | } 189 | } 190 | else 191 | { 192 | throw new Win32Exception(); 193 | } 194 | } 195 | else 196 | { 197 | throw new Win32Exception(); 198 | } 199 | */ 200 | } 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /StartProcessAsUser/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("StartProcessAsUser")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("StartProcessAsUser")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2bb361d6-5063-4cbb-9d8f-cebed9a02e12")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /StartProcessAsUser/StartProcessAsUser.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6E2794EC-90F0-49AC-B80A-4CE091152499} 8 | Exe 9 | Properties 10 | StartProcessAsUser 11 | StartProcessAsUser 12 | v4.5 13 | 512 14 | 15 | 16 | x64 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | false 26 | false 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | true 37 | false 38 | false 39 | 40 | 41 | app.manifest 42 | 43 | 44 | 45 | False 46 | ..\lib\AsproLock.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {3324447d-2457-404a-a1d8-b739c5150d2d} 63 | StartProcessLib 64 | 65 | 66 | 67 | 74 | -------------------------------------------------------------------------------- /StartProcessAsUser/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /StartProcessLib/DesktopPermissionManager.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib 2 | { 3 | using System; 4 | using System.Security.AccessControl; 5 | using Asprosys.Security.AccessControl; 6 | using NLog; 7 | using PInvoke; 8 | 9 | public class DesktopPermissionManager 10 | { 11 | private readonly Logger log = LogManager.GetCurrentClassLogger(); 12 | private readonly string userName; 13 | 14 | public DesktopPermissionManager(string userName) 15 | { 16 | if (String.IsNullOrWhiteSpace(userName)) 17 | { 18 | throw new ArgumentNullException("userName"); 19 | } 20 | this.userName = userName; 21 | } 22 | 23 | public void AddDesktopPermission() 24 | { 25 | try 26 | { 27 | IntPtr hWinSta = NativeMethods.GetProcessWindowStation(); 28 | var ws = new WindowStationSecurity(hWinSta, AccessControlSections.Access); 29 | ws.AddAccessRule(new WindowStationAccessRule(userName, WindowStationRights.AllAccess, AccessControlType.Allow)); 30 | ws.AcceptChanges(); 31 | 32 | IntPtr hDesk = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()); 33 | var ds = new DesktopSecurity(hDesk, AccessControlSections.Access); 34 | ds.AddAccessRule(new DesktopAccessRule(userName, DesktopRights.AllAccess, AccessControlType.Allow)); 35 | ds.AcceptChanges(); 36 | } 37 | catch (Exception ex) 38 | { 39 | log.ErrorException("Exception adding desktop permissions!", ex); 40 | } 41 | } 42 | 43 | public void RemoveDesktopPermission() 44 | { 45 | try 46 | { 47 | IntPtr hWinSta = NativeMethods.GetProcessWindowStation(); 48 | var ws = new WindowStationSecurity(hWinSta, AccessControlSections.Access); 49 | ws.RemoveAccessRule(new WindowStationAccessRule(userName, WindowStationRights.AllAccess, AccessControlType.Allow)); 50 | ws.AcceptChanges(); 51 | 52 | IntPtr hDesk = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()); 53 | var ds = new DesktopSecurity(hDesk, AccessControlSections.Access); 54 | ds.RemoveAccessRule(new DesktopAccessRule(userName, DesktopRights.AllAccess, AccessControlType.Allow)); 55 | ds.AcceptChanges(); 56 | } 57 | catch (Exception ex) 58 | { 59 | log.ErrorException("Exception removing desktop permissions!", ex); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /StartProcessLib/JobObject.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2011 Uhuru Software, Inc., All Rights Reserved 4 | // 5 | // Modified by Luke Bakken from the original. 6 | // ----------------------------------------------------------------------- 7 | 8 | namespace StartProcessLib 9 | { 10 | using System; 11 | using System.Collections.Generic; 12 | using System.ComponentModel; 13 | using System.Diagnostics; 14 | using System.Runtime.InteropServices; 15 | using System.Security.Permissions; 16 | using PInvoke; 17 | 18 | /// 19 | /// Is a class that manages a Windows Job Object. Job Objects allows to group a number of processes and 20 | /// perform some aggregate operations. It is a good tool for enforcing resource sandboxing for processes. 21 | /// 22 | [SecurityPermission(SecurityAction.LinkDemand)] 23 | //// [SecurityCriticalAttribute] 24 | public class JobObject : IDisposable 25 | { 26 | /// 27 | /// The Windows Handle 28 | /// 29 | private NativeMethods.JobObjectHandle jobHandle; 30 | 31 | /// 32 | /// Flag to kill processes on job close. 33 | /// 34 | private bool killProcessesOnJobClose = true; 35 | 36 | /// 37 | /// Die on unhandled exception. 38 | /// 39 | private bool dieOnUnhandledException = false; 40 | 41 | /// 42 | /// Allow child process breakaway. 43 | /// 44 | private bool allowChildProcessesBreakaway = false; 45 | 46 | /// 47 | /// Breakaway child processes by default. 48 | /// 49 | private bool alwaysBreakawayChildProcesses = false; 50 | 51 | /// 52 | /// Maximum number of active processes. 53 | /// 54 | private uint activeProcessesLimit = 0; 55 | 56 | /// 57 | /// The memory limit of the Job Object. 58 | /// 59 | private long jobMemoryLimit = 0; 60 | 61 | /// 62 | /// The memory limit of each process in the Job Object. 63 | /// 64 | private long processMemoryLimit = 0; 65 | 66 | /// 67 | /// Flag if the job processor user time limit has changed. 68 | /// 69 | private bool jobUserTimeLimitChanged = false; 70 | 71 | /// 72 | /// The processor user time limit for the job. 73 | /// 74 | private long jobUserTimeLimit = 0; 75 | 76 | /// 77 | /// The user time limit per each process in the job. 78 | /// 79 | private long processUserTimeLimit = 0; 80 | 81 | /// 82 | /// The priority class of the Job Object. 83 | /// 84 | private uint priorityClass = 0; 85 | 86 | /// 87 | /// The scheduling class. 88 | /// 89 | private uint schedulingClass = 0; 90 | 91 | /// 92 | /// The processor affinity. 93 | /// 94 | private IntPtr affinity = IntPtr.Zero; 95 | 96 | /// 97 | /// The read IO operations count for the whole job. 98 | /// 99 | private long ioReadOperationsCount = 0; 100 | 101 | /// 102 | /// The write IO operations count for the whole job. 103 | /// 104 | private long ioWriteOperationsCount = 0; 105 | 106 | /// 107 | /// Other IO operations count for the while job. 108 | /// 109 | private long ioOtherOperationsCount = 0; 110 | 111 | /// 112 | /// Total IO bytes read by the job. 113 | /// 114 | private long ioReadBytes = 0; 115 | 116 | /// 117 | /// Total IO bytes written by the job. 118 | /// 119 | private long ioWriteBytes = 0; 120 | 121 | /// 122 | /// Total IO bytes used in other operations. 123 | /// 124 | private long ioOtherBytes = 0; 125 | 126 | /// 127 | /// Peak memory usage by the job. 128 | /// 129 | private ulong peakJobMemory = 0; 130 | 131 | /// 132 | /// Peak memory usage by a process. 133 | /// 134 | private ulong peakProcessMemory = 0; 135 | 136 | /// 137 | /// Total user processor time used by the job. 138 | /// 139 | private ulong userProcessorTime = 0; 140 | 141 | /// 142 | /// Total kernel processor time used by the job. 143 | /// 144 | private ulong kernelProcessorTime = 0; 145 | 146 | /// 147 | /// The processes in the job. 148 | /// 149 | private Process[] jobProcesses; 150 | 151 | /// 152 | /// Initializes a new instance of the class. The Windows Job Object is unnamed. 153 | /// 154 | public JobObject() 155 | : this(null) 156 | { 157 | } 158 | 159 | /// 160 | /// Initializes a new instance of the class. If a Job Object with the specified name exists, 161 | /// then the Job Object is opened; if not, the Job Object with the specified named is opened. 162 | /// 163 | /// Name of the job object. 164 | public JobObject(string jobObjectName) 165 | { 166 | if (string.IsNullOrEmpty(jobObjectName)) 167 | { 168 | jobObjectName = null; 169 | } 170 | 171 | this.jobHandle = NativeMethods.CreateJobObject(IntPtr.Zero, jobObjectName); 172 | if (this.jobHandle.IsInvalid) 173 | { 174 | if (jobObjectName == null) 175 | { 176 | int error = Marshal.GetLastWin32Error(); 177 | throw new Win32Exception(error, "CreateJobObject failed."); 178 | } 179 | else 180 | { 181 | // JOB_OBJECT_ALL_ACCESS = 0x1F001F 182 | this.jobHandle = NativeMethods.OpenJobObject(0x1F001F, false, jobObjectName); 183 | if (this.jobHandle.IsInvalid) 184 | { 185 | int error = Marshal.GetLastWin32Error(); 186 | throw new Win32Exception(error, "OpenJobObject failed."); 187 | } 188 | } 189 | } 190 | 191 | this.UpdateExtendedLimit(); 192 | } 193 | 194 | /// 195 | /// Finalizes an instance of the JobObject class. Releases unmanaged resources and performs other cleanup operations before the 196 | /// is reclaimed by garbage collection. 197 | /// 198 | ~JobObject() 199 | { 200 | this.Dispose(false); 201 | } 202 | 203 | /// 204 | /// Gets or sets a value indicating whether to kill the processes when the Job Object is closed. 205 | /// 206 | /// 207 | /// true if [kill processes on job close]; otherwise, false. 208 | /// 209 | public bool KillProcessesOnJobClose 210 | { 211 | get 212 | { 213 | return this.killProcessesOnJobClose; 214 | } 215 | 216 | set 217 | { 218 | this.killProcessesOnJobClose = value; 219 | this.UpdateExtendedLimit(); 220 | } 221 | } 222 | 223 | /// 224 | /// Gets or sets a value indicating whether a process to die on an unhandled exception. 225 | /// 226 | /// 227 | /// true if [die on unhandled exception]; otherwise, false. 228 | /// 229 | public bool DieOnUnhandledException 230 | { 231 | get 232 | { 233 | return this.dieOnUnhandledException; 234 | } 235 | 236 | set 237 | { 238 | this.dieOnUnhandledException = value; 239 | this.UpdateExtendedLimit(); 240 | } 241 | } 242 | 243 | /// 244 | /// Gets or sets a value indicating whether processes are allowed to create processes outside the Job Object. 245 | /// 246 | /// 247 | /// true if [allow child processes breakaway]; otherwise, false. 248 | /// 249 | public bool AllowChildProcessesBreakaway 250 | { 251 | get 252 | { 253 | return this.allowChildProcessesBreakaway; 254 | } 255 | 256 | set 257 | { 258 | this.allowChildProcessesBreakaway = value; 259 | this.UpdateExtendedLimit(); 260 | } 261 | } 262 | 263 | /// 264 | /// Gets or sets a value indicating whether child processes are not added to the Job Object. 265 | /// 266 | /// 267 | /// true if [always breakaway child processes]; otherwise, false. 268 | /// 269 | public bool AlwaysBreakawayChildProcesses 270 | { 271 | get 272 | { 273 | return this.alwaysBreakawayChildProcesses; 274 | } 275 | 276 | set 277 | { 278 | this.alwaysBreakawayChildProcesses = value; 279 | this.UpdateExtendedLimit(); 280 | } 281 | } 282 | 283 | /// 284 | /// Gets or sets the active processes in the Job Object. Set to 0 (zero) to disable the limit. 285 | /// 286 | /// 287 | /// The active processes. 288 | /// 289 | public int ActiveProcessesLimit 290 | { 291 | get 292 | { 293 | return (int)this.activeProcessesLimit; 294 | } 295 | 296 | set 297 | { 298 | this.activeProcessesLimit = (uint)value; 299 | this.UpdateExtendedLimit(); 300 | } 301 | } 302 | 303 | /// 304 | /// Gets or sets the memory in bytes limit enforced per process. Set to 0 (zero) to disable the limit. 305 | /// 306 | /// 307 | /// The process memory limit. 308 | /// 309 | public long ProcessMemoryLimit 310 | { 311 | get 312 | { 313 | return (long)this.processMemoryLimit; 314 | } 315 | 316 | set 317 | { 318 | this.processMemoryLimit = (long)value; 319 | this.UpdateExtendedLimit(); 320 | } 321 | } 322 | 323 | /// 324 | /// Gets or sets the memory limit in bytes of the entire Job Object. Set to 0 (zero) to disable the limit. 325 | /// 326 | /// 327 | /// The job memory limit. 328 | /// 329 | public long JobMemoryLimit 330 | { 331 | get 332 | { 333 | return this.jobMemoryLimit; 334 | } 335 | 336 | set 337 | { 338 | this.jobMemoryLimit = value; 339 | this.UpdateExtendedLimit(); 340 | } 341 | } 342 | 343 | /// 344 | /// Gets or sets the process user time limit. It is enforced per process. Set to 0 (zero) to disable the limit. 345 | /// 346 | /// 347 | /// The process user time limit. 348 | /// 349 | public TimeSpan ProcessUserTimeLimit 350 | { 351 | get 352 | { 353 | return new TimeSpan(this.processUserTimeLimit); 354 | } 355 | 356 | set 357 | { 358 | this.processUserTimeLimit = value.Ticks; 359 | this.UpdateExtendedLimit(); 360 | } 361 | } 362 | 363 | /// 364 | /// Gets or sets the Job Object user time limit. Every process user time is accounted. Set to 0 (zero) to disable the limit. 365 | /// 366 | /// 367 | /// The job user time limit. 368 | /// 369 | public TimeSpan JobUserTimeLimit 370 | { 371 | get 372 | { 373 | return new TimeSpan(this.jobUserTimeLimit); 374 | } 375 | 376 | set 377 | { 378 | this.jobUserTimeLimit = value.Ticks; 379 | this.jobUserTimeLimitChanged = true; 380 | this.UpdateExtendedLimit(); 381 | } 382 | } 383 | 384 | /// 385 | /// Gets or sets the priority class of the Job Object. 386 | /// 387 | /// 388 | /// The priority class. 389 | /// 390 | public ProcessPriorityClass PriorityClass 391 | { 392 | get 393 | { 394 | return (ProcessPriorityClass)this.priorityClass; 395 | } 396 | 397 | set 398 | { 399 | this.priorityClass = (uint)value; 400 | this.UpdateExtendedLimit(); 401 | } 402 | } 403 | 404 | /// 405 | /// Gets or sets the scheduling class of the JobObject. 406 | /// 407 | /// 408 | /// The scheduling class. 409 | /// 410 | public int SchedulingClass 411 | { 412 | get 413 | { 414 | return (int)this.schedulingClass; 415 | } 416 | 417 | set 418 | { 419 | this.schedulingClass = (uint)value; 420 | this.UpdateExtendedLimit(); 421 | } 422 | } 423 | 424 | /// 425 | /// Gets or sets the processor affinity, enforced for every process. 426 | /// 427 | /// 428 | /// The affinity. 429 | /// 430 | public IntPtr Affinity 431 | { 432 | get 433 | { 434 | return this.affinity; 435 | } 436 | 437 | set 438 | { 439 | this.affinity = value; 440 | this.UpdateExtendedLimit(); 441 | } 442 | } 443 | 444 | /// 445 | /// Gets the total IO bytes read by every process in the Job Object. 446 | /// 447 | public long IOReadBytes 448 | { 449 | get 450 | { 451 | this.QueryBasicAndIoAccounting(); 452 | return this.ioReadBytes; 453 | } 454 | } 455 | 456 | /// 457 | /// Gets the total IO bytes written by every process in the Job Object. 458 | /// 459 | public long IOWriteBytes 460 | { 461 | get 462 | { 463 | this.QueryBasicAndIoAccounting(); 464 | return this.ioWriteBytes; 465 | } 466 | } 467 | 468 | /// 469 | /// Gets the total IO bytes used in other operations by every process in the Job Object. 470 | /// 471 | public long IOOtherBytes 472 | { 473 | get 474 | { 475 | this.QueryBasicAndIoAccounting(); 476 | return this.ioOtherBytes; 477 | } 478 | } 479 | 480 | /// 481 | /// Gets the IO read operations count preformed by every process in the Job Object. 482 | /// 483 | public long IOReadOperationsCount 484 | { 485 | get 486 | { 487 | this.QueryBasicAndIoAccounting(); 488 | return this.ioReadOperationsCount; 489 | } 490 | } 491 | 492 | /// 493 | /// Gets the IO write operations count preformed by every process in the Job Object. 494 | /// 495 | public long IOWriteOperationsCount 496 | { 497 | get 498 | { 499 | this.QueryBasicAndIoAccounting(); 500 | return this.ioWriteOperationsCount; 501 | } 502 | } 503 | 504 | /// 505 | /// Gets the other IO operations count preformed by every process in the Job Object. 506 | /// 507 | public long IOOtherOperationsCount 508 | { 509 | get 510 | { 511 | this.QueryBasicAndIoAccounting(); 512 | return this.ioOtherOperationsCount; 513 | } 514 | } 515 | 516 | /// 517 | /// Gets the peak memory in bytes used by the Job Object at any given time. 518 | /// 519 | public long PeakJobMemory 520 | { 521 | get 522 | { 523 | this.QueryExtendedLimitInformation(); 524 | return (long)this.peakJobMemory; 525 | } 526 | } 527 | 528 | /// 529 | /// Gets the peak memory in bytes used by a process. 530 | /// 531 | public long PeakProcessMemory 532 | { 533 | get 534 | { 535 | this.QueryExtendedLimitInformation(); 536 | return (long)this.peakProcessMemory; 537 | } 538 | } 539 | 540 | /// 541 | /// Gets the total processor time used by each process. 542 | /// 543 | public TimeSpan TotalProcessorTime 544 | { 545 | get 546 | { 547 | this.QueryBasicAndIoAccounting(); 548 | return new TimeSpan((long)this.userProcessorTime + (long)this.kernelProcessorTime); 549 | } 550 | } 551 | 552 | /// 553 | /// Gets the user processor time used by each process. 554 | /// 555 | public TimeSpan UserProcessorTime 556 | { 557 | get 558 | { 559 | this.QueryBasicAndIoAccounting(); 560 | return new TimeSpan((long)this.userProcessorTime); 561 | } 562 | } 563 | 564 | /// 565 | /// Gets the kernel processor time used by each process. 566 | /// 567 | public TimeSpan KernelProcessorTime 568 | { 569 | get 570 | { 571 | this.QueryBasicAndIoAccounting(); 572 | return new TimeSpan((long)this.kernelProcessorTime); 573 | } 574 | } 575 | 576 | /// 577 | /// Gets the working set memory in bytes of the Job Object. 578 | /// 579 | public long WorkingSetMemory 580 | { 581 | get 582 | { 583 | this.QueryProcessIds(); 584 | long res = 0; 585 | foreach (Process p in this.jobProcesses) 586 | { 587 | res += p.WorkingSet64; 588 | } 589 | 590 | return res; 591 | } 592 | } 593 | 594 | /// 595 | /// Gets the virtual memory in bytes. 596 | /// 597 | public long VirtualMemory 598 | { 599 | get 600 | { 601 | this.QueryProcessIds(); 602 | long res = 0; 603 | foreach (Process p in this.jobProcesses) 604 | { 605 | res += p.VirtualMemorySize64; 606 | } 607 | 608 | return res; 609 | } 610 | } 611 | 612 | /// 613 | /// Gets the private memory in bytes. 614 | /// 615 | public long PrivateMemory 616 | { 617 | get 618 | { 619 | this.QueryProcessIds(); 620 | long res = 0; 621 | foreach (Process p in this.jobProcesses) 622 | { 623 | res += p.PrivateMemorySize64; 624 | } 625 | 626 | return res; 627 | } 628 | } 629 | 630 | /// 631 | /// Gets the paged memory in bytes. 632 | /// 633 | public long PagedMemory 634 | { 635 | get 636 | { 637 | this.QueryProcessIds(); 638 | long res = 0; 639 | foreach (Process p in this.jobProcesses) 640 | { 641 | res += p.PagedMemorySize64; 642 | } 643 | 644 | return res; 645 | } 646 | } 647 | 648 | /// 649 | /// Gets the paged system memory in bytes. 650 | /// 651 | public long PagedSystemMemory 652 | { 653 | get 654 | { 655 | this.QueryProcessIds(); 656 | long res = 0; 657 | foreach (Process p in this.jobProcesses) 658 | { 659 | res += p.PagedSystemMemorySize64; 660 | } 661 | 662 | return res; 663 | } 664 | } 665 | 666 | /// 667 | /// Gets the non paged system memory in bytes. 668 | /// 669 | public long NonPagedSystemMemory 670 | { 671 | get 672 | { 673 | this.QueryProcessIds(); 674 | long res = 0; 675 | foreach (Process p in this.jobProcesses) 676 | { 677 | res += p.NonpagedSystemMemorySize64; 678 | } 679 | 680 | return res; 681 | } 682 | } 683 | 684 | /// 685 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 686 | /// 687 | public void Dispose() 688 | { 689 | this.Dispose(true); 690 | GC.SuppressFinalize(this); 691 | } 692 | 693 | /// 694 | /// Adds a process to the current Job Object, for which the Job Object limits apply. 695 | /// 696 | /// The process to be added. 697 | public void AddProcess(Process process) 698 | { 699 | if (process == null) 700 | { 701 | throw new ArgumentNullException("process"); 702 | } 703 | 704 | this.AddProcess(process.Handle); 705 | } 706 | 707 | /// 708 | /// Determines whether the specified process is in the Job Object 709 | /// 710 | /// The process to be checked for. 711 | /// 712 | /// true if the specified process has the process; otherwise, false. 713 | /// 714 | public bool HasProcess(Process process) 715 | { 716 | if (process == null) 717 | { 718 | throw new ArgumentNullException("process"); 719 | } 720 | 721 | return this.HasProcess(process.Handle); 722 | } 723 | 724 | /// 725 | /// Terminates all the processes in the Job Object. 726 | /// 727 | /// The exit code. 728 | public void TerminateProcesses(int exitCode) 729 | { 730 | NativeMethods.TerminateJobObject(this.jobHandle, (uint)exitCode); 731 | } 732 | 733 | /// 734 | /// Gets all the processes included in the Job Object. 735 | /// 736 | /// The list of processes. 737 | public Process[] GetJobProcesses() 738 | { 739 | this.QueryProcessIds(); 740 | return this.jobProcesses; 741 | } 742 | 743 | /// 744 | /// Releases unmanaged and - optionally - managed resources 745 | /// 746 | /// true to release both managed and unmanaged resources; false to release only unmanaged resources. 747 | protected virtual void Dispose(bool disposing) 748 | { 749 | if (disposing) 750 | { 751 | this.jobHandle.Close(); 752 | } 753 | } 754 | 755 | /// 756 | /// Determines whether the specified process handle is included in the Job Object. 757 | /// 758 | /// The process handle. 759 | /// 760 | /// true if the specified process handle has process; otherwise, false. 761 | /// 762 | private bool HasProcess(IntPtr processHandle) 763 | { 764 | bool result; 765 | bool success = NativeMethods.IsProcessInJob(processHandle, this.jobHandle, out result); 766 | if (success == false) 767 | { 768 | int error = Marshal.GetLastWin32Error(); 769 | throw new Win32Exception(error, "IsProcessInJob failed."); 770 | } 771 | 772 | return result; 773 | } 774 | 775 | /// 776 | /// Adds the process handle to the Job object. 777 | /// 778 | /// The process handle. 779 | public void AddProcess(IntPtr processHandle) 780 | { 781 | bool success = NativeMethods.AssignProcessToJobObject(this.jobHandle, processHandle); 782 | if (success == false) 783 | { 784 | int error = Marshal.GetLastWin32Error(); 785 | throw new Win32Exception(error, "AssignProcessToJobObject failed."); 786 | } 787 | } 788 | 789 | /// 790 | /// Queries the process ids. 791 | /// 792 | private void QueryProcessIds() 793 | { 794 | NativeMethods.JOBOBJECT_BASIC_PROCESS_ID_LIST processList = new NativeMethods.JOBOBJECT_BASIC_PROCESS_ID_LIST(); 795 | processList.NumberOfAssignedProcesses = NativeMethods.JOBOBJECT_BASIC_PROCESS_ID_LIST.MaxProcessListLength; 796 | processList.NumberOfProcessIdsInList = 0; 797 | processList.ProcessIdList = null; 798 | 799 | int processListLength = Marshal.SizeOf(typeof(NativeMethods.JOBOBJECT_BASIC_PROCESS_ID_LIST)); 800 | IntPtr processListPtr = Marshal.AllocHGlobal(processListLength); 801 | 802 | try 803 | { 804 | Marshal.StructureToPtr(processList, processListPtr, false); 805 | 806 | bool success = NativeMethods.QueryInformationJobObject(this.jobHandle, NativeMethods.JobObjectInfoClass.JobObjectBasicProcessIdList, processListPtr, (uint)processListLength, IntPtr.Zero); 807 | 808 | if (success == false) 809 | { 810 | int error = Marshal.GetLastWin32Error(); 811 | throw new Win32Exception(error, "QueryInformationJobObject failed."); 812 | } 813 | 814 | processList = (NativeMethods.JOBOBJECT_BASIC_PROCESS_ID_LIST)Marshal.PtrToStructure(processListPtr, typeof(NativeMethods.JOBOBJECT_BASIC_PROCESS_ID_LIST)); 815 | 816 | List pss = new List(); 817 | 818 | for (int i = 0; i < processList.NumberOfProcessIdsInList; i++) 819 | { 820 | try 821 | { 822 | pss.Add(Process.GetProcessById((int)processList.ProcessIdList[i])); 823 | } 824 | catch (ArgumentException) 825 | { 826 | } 827 | } 828 | 829 | this.jobProcesses = pss.ToArray(); 830 | } 831 | finally 832 | { 833 | Marshal.FreeHGlobal(processListPtr); 834 | } 835 | } 836 | 837 | /// 838 | /// Updates the extended limit. 839 | /// 840 | private void UpdateExtendedLimit() 841 | { 842 | NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedLimit = new NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); 843 | NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit = new NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION(); 844 | 845 | basicLimit.LimitFlags = 0; 846 | 847 | if (this.killProcessesOnJobClose) 848 | { 849 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; 850 | } 851 | 852 | if (this.dieOnUnhandledException) 853 | { 854 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; 855 | } 856 | 857 | if (this.allowChildProcessesBreakaway) 858 | { 859 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_BREAKAWAY_OK; 860 | } 861 | 862 | if (this.alwaysBreakawayChildProcesses) 863 | { 864 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; 865 | } 866 | 867 | if (this.activeProcessesLimit != 0) 868 | { 869 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_ACTIVE_PROCESS; 870 | basicLimit.ActiveProcessLimit = this.activeProcessesLimit; 871 | } 872 | 873 | if (this.processMemoryLimit != 0) 874 | { 875 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PROCESS_MEMORY; 876 | extendedLimit.ProcessMemoryLimit = (IntPtr)this.processMemoryLimit; 877 | } 878 | 879 | if (this.jobMemoryLimit != 0) 880 | { 881 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_JOB_MEMORY; 882 | extendedLimit.JobMemoryLimit = (IntPtr)this.jobMemoryLimit; 883 | } 884 | 885 | if (this.processUserTimeLimit != 0) 886 | { 887 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PROCESS_TIME; 888 | basicLimit.PerProcessUserTimeLimit = this.processUserTimeLimit; 889 | } 890 | 891 | if (this.jobUserTimeLimit != 0) 892 | { 893 | if (this.jobUserTimeLimitChanged) 894 | { 895 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_JOB_TIME; 896 | basicLimit.PerJobUserTimeLimit = this.jobUserTimeLimit; 897 | this.jobUserTimeLimitChanged = false; 898 | } 899 | else 900 | { 901 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME; 902 | } 903 | } 904 | 905 | if (this.priorityClass != 0) 906 | { 907 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PRIORITY_CLASS; 908 | basicLimit.PriorityClass = this.priorityClass; 909 | } 910 | 911 | if (this.schedulingClass != 0) 912 | { 913 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_SCHEDULING_CLASS; 914 | basicLimit.SchedulingClass = this.schedulingClass; 915 | } 916 | 917 | if (this.affinity != IntPtr.Zero) 918 | { 919 | basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_AFFINITY; 920 | basicLimit.Affinity = this.affinity; 921 | } 922 | 923 | extendedLimit.BasicLimitInformation = basicLimit; 924 | 925 | int extendedLimitLength = Marshal.SizeOf(typeof(NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); 926 | IntPtr extendedLimitPtr = Marshal.AllocHGlobal(extendedLimitLength); 927 | 928 | try 929 | { 930 | Marshal.StructureToPtr(extendedLimit, extendedLimitPtr, false); 931 | 932 | bool success = NativeMethods.SetInformationJobObject(this.jobHandle, NativeMethods.JobObjectInfoClass.JobObjectExtendedLimitInformation, extendedLimitPtr, (uint)extendedLimitLength); 933 | 934 | if (success == false) 935 | { 936 | int error = Marshal.GetLastWin32Error(); 937 | throw new Win32Exception(error, "SetInformationJobObject failed."); 938 | } 939 | } 940 | finally 941 | { 942 | Marshal.FreeHGlobal(extendedLimitPtr); 943 | } 944 | } 945 | 946 | /// 947 | /// Queries the basic and IO accounting. 948 | /// 949 | private void QueryBasicAndIoAccounting() 950 | { 951 | NativeMethods.JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION accounting = new NativeMethods.JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION(); 952 | accounting.BasicInfo = new NativeMethods.JOBOBJECT_BASIC_ACCOUNTING_INFORMATION(); 953 | accounting.IoInfo = new NativeMethods.IO_COUNTERS(); 954 | 955 | int accountingLength = Marshal.SizeOf(typeof(NativeMethods.JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION)); 956 | IntPtr accountingPtr = Marshal.AllocHGlobal(accountingLength); 957 | 958 | try 959 | { 960 | bool success = NativeMethods.QueryInformationJobObject(this.jobHandle, NativeMethods.JobObjectInfoClass.JobObjectBasicAndIoAccountingInformation, accountingPtr, (uint)accountingLength, IntPtr.Zero); 961 | 962 | if (success == false) 963 | { 964 | int error = Marshal.GetLastWin32Error(); 965 | throw new Win32Exception(error, "QueryInformationJobObject failed."); 966 | } 967 | 968 | accounting = (NativeMethods.JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION)Marshal.PtrToStructure(accountingPtr, typeof(NativeMethods.JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION)); 969 | 970 | this.userProcessorTime = (ulong)accounting.BasicInfo.TotalUserTime; 971 | this.kernelProcessorTime = (ulong)accounting.BasicInfo.TotalKernelTime; 972 | 973 | this.ioReadBytes = (long)accounting.IoInfo.ReadTransferCount; 974 | this.ioWriteBytes = (long)accounting.IoInfo.WriteTransferCount; 975 | this.ioOtherBytes = (long)accounting.IoInfo.OtherTransferCount; 976 | this.ioReadOperationsCount = (long)accounting.IoInfo.ReadOperationCount; 977 | this.ioWriteOperationsCount = (long)accounting.IoInfo.WriteOperationCount; 978 | this.ioOtherOperationsCount = (long)accounting.IoInfo.OtherOperationCount; 979 | } 980 | finally 981 | { 982 | Marshal.FreeHGlobal(accountingPtr); 983 | } 984 | } 985 | 986 | /// 987 | /// Queries the extended limit information. 988 | /// 989 | private void QueryExtendedLimitInformation() 990 | { 991 | NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedLimit; 992 | 993 | int extenedLimitLength = Marshal.SizeOf(typeof(NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); 994 | IntPtr extendedLimitPtr = Marshal.AllocHGlobal(extenedLimitLength); 995 | 996 | try 997 | { 998 | bool success = NativeMethods.QueryInformationJobObject(this.jobHandle, NativeMethods.JobObjectInfoClass.JobObjectExtendedLimitInformation, extendedLimitPtr, (uint)extenedLimitLength, IntPtr.Zero); 999 | 1000 | if (success == false) 1001 | { 1002 | int error = Marshal.GetLastWin32Error(); 1003 | throw new Win32Exception(error, "QueryInformationJobObject failed."); 1004 | } 1005 | 1006 | extendedLimit = (NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION)Marshal.PtrToStructure(extendedLimitPtr, typeof(NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); 1007 | 1008 | this.peakJobMemory = (ulong)extendedLimit.PeakJobMemoryUsed; 1009 | this.peakProcessMemory = (ulong)extendedLimit.PeakProcessMemoryUsed; 1010 | } 1011 | finally 1012 | { 1013 | Marshal.FreeHGlobal(extendedLimitPtr); 1014 | } 1015 | } 1016 | } 1017 | } 1018 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/CloseHandle.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | public partial class NativeMethods 7 | { 8 | [DllImport("kernel32.dll", SetLastError=true)] 9 | public static extern bool CloseHandle(IntPtr handle); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | 5 | public partial class NativeMethods 6 | { 7 | public class Constants 8 | { 9 | public const Int32 GENERIC_ALL_ACCESS = 0x10000000; 10 | public const UInt32 INFINITE = 0xFFFFFFFF; 11 | public const UInt32 WAIT_FAILED = 0xFFFFFFFF; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/CreateEnvironmentBlock.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | public partial class NativeMethods 7 | { 8 | // http://www.pinvoke.net/default.aspx/userenv.createenvironmentblock 9 | [DllImport("userenv.dll", CharSet = CharSet.Unicode, SetLastError = true)] 10 | public static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/CreateProcess.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | public partial class NativeMethods 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 10 | public static extern IntPtr GetEnvironmentStrings(); 11 | 12 | [DllImport("kernel32.dll")] 13 | public static extern uint ResumeThread(IntPtr hThread); 14 | 15 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 16 | public static extern bool CreateProcess 17 | ( 18 | String lpApplicationName, 19 | String lpCommandLine, 20 | SecurityAttributes lpProcessAttributes, 21 | SecurityAttributes lpThreadAttributes, 22 | Boolean bInheritHandles, 23 | CreateProcessFlags dwCreationFlags, 24 | IntPtr lpEnvironment, 25 | String lpCurrentDirectory, 26 | [In] StartupInfo lpStartupInfo, 27 | out ProcessInformation lpProcessInformation 28 | ); 29 | 30 | [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 31 | public static extern Boolean CreateProcessAsUser 32 | ( 33 | IntPtr hToken, 34 | String lpApplicationName, 35 | [In] StringBuilder lpCommandLine, 36 | SecurityAttributes lpProcessAttributes, 37 | SecurityAttributes lpThreadAttributes, 38 | Boolean bInheritHandles, 39 | CreateProcessFlags dwCreationFlags, 40 | IntPtr lpEnvironment, 41 | String lpCurrentDirectory, 42 | [In] StartupInfo lpStartupInfo, 43 | out ProcessInformation lpProcessInformation 44 | ); 45 | 46 | [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 47 | public static extern bool CreateProcessWithLogon 48 | ( 49 | String lpUserName, 50 | String lpDomain, 51 | String lpPassword, 52 | LogonFlags dwLogonFlags, 53 | String lpApplicationName, 54 | StringBuilder lpCommandLine, 55 | CreateProcessFlags dwCreationFlags, 56 | IntPtr lpEnvironment, 57 | String lpCurrentDirectory, 58 | [In] StartupInfo lpStartupInfo, 59 | out ProcessInformation lpProcessInformation 60 | ); 61 | 62 | [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)] 63 | public static extern bool CreateProcessWithToken 64 | ( 65 | IntPtr hToken, 66 | LogonFlags dwLogonFlags, 67 | String lpApplicationName, 68 | String lpCommandLine, 69 | CreateProcessFlags dwCreationFlags, 70 | IntPtr lpEnvironment, 71 | String lpCurrentDirectory, 72 | [In] StartupInfo lpStartupInfo, 73 | out ProcessInformation lpProcessInformation 74 | ); 75 | 76 | [Flags] 77 | public enum LogonFlags 78 | { 79 | LOGON_WITH_PROFILE = 0x00000001, 80 | LOGON_NETCREDENTIALS_ONLY = 0x00000002 81 | } 82 | 83 | [StructLayout(LayoutKind.Sequential)] 84 | public class StartupInfo 85 | { 86 | public Int32 cb = 0; 87 | public IntPtr lpReserved = IntPtr.Zero; 88 | public IntPtr lpDesktop = IntPtr.Zero; // MUST be Zero 89 | public IntPtr lpTitle = IntPtr.Zero; 90 | public Int32 dwX = 0; 91 | public Int32 dwY = 0; 92 | public Int32 dwXSize = 0; 93 | public Int32 dwYSize = 0; 94 | public Int32 dwXCountChars = 0; 95 | public Int32 dwYCountChars = 0; 96 | public Int32 dwFillAttribute = 0; 97 | public Int32 dwFlags = 0; 98 | public Int16 wShowWindow = 0; 99 | public Int16 cbReserved2 = 0; 100 | public IntPtr lpReserved2 = IntPtr.Zero; 101 | public IntPtr hStdInput = IntPtr.Zero; 102 | public IntPtr hStdOutput = IntPtr.Zero; 103 | public IntPtr hStdError = IntPtr.Zero; 104 | 105 | public StartupInfo() 106 | { 107 | this.cb = Marshal.SizeOf(this); 108 | } 109 | } 110 | 111 | [StructLayout(LayoutKind.Sequential)] 112 | public struct ProcessInformation 113 | { 114 | public IntPtr hProcess; 115 | public IntPtr hThread; 116 | public Int32 dwProcessId; 117 | public Int32 dwThreadId; 118 | } 119 | 120 | [Flags] 121 | public enum CreateProcessFlags : uint 122 | { 123 | DEBUG_PROCESS = 0x00000001, 124 | DEBUG_ONLY_THIS_PROCESS = 0x00000002, 125 | CREATE_SUSPENDED = 0x00000004, 126 | DETACHED_PROCESS = 0x00000008, 127 | CREATE_NEW_CONSOLE = 0x00000010, 128 | NORMAL_PRIORITY_CLASS = 0x00000020, 129 | IDLE_PRIORITY_CLASS = 0x00000040, 130 | HIGH_PRIORITY_CLASS = 0x00000080, 131 | REALTIME_PRIORITY_CLASS = 0x00000100, 132 | CREATE_NEW_PROCESS_GROUP = 0x00000200, 133 | CREATE_UNICODE_ENVIRONMENT = 0x00000400, 134 | CREATE_SEPARATE_WOW_VDM = 0x00000800, 135 | CREATE_SHARED_WOW_VDM = 0x00001000, 136 | CREATE_FORCEDOS = 0x00002000, 137 | BELOW_NORMAL_PRIORITY_CLASS = 0x00004000, 138 | ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000, 139 | INHERIT_PARENT_AFFINITY = 0x00010000, 140 | INHERIT_CALLER_PRIORITY = 0x00020000, 141 | CREATE_PROTECTED_PROCESS = 0x00040000, 142 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000, 143 | PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000, 144 | PROCESS_MODE_BACKGROUND_END = 0x00200000, 145 | CREATE_BREAKAWAY_FROM_JOB = 0x01000000, 146 | CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000, 147 | CREATE_DEFAULT_ERROR_MODE = 0x04000000, 148 | CREATE_NO_WINDOW = 0x08000000, 149 | PROFILE_USER = 0x10000000, 150 | PROFILE_KERNEL = 0x20000000, 151 | PROFILE_SERVER = 0x40000000, 152 | CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000, 153 | } 154 | 155 | [Flags] 156 | public enum DuplicateOptions : uint 157 | { 158 | DUPLICATE_CLOSE_SOURCE = 0x00000001, 159 | DUPLICATE_SAME_ACCESS = 0x00000002 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/DuplicateTokenEx.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | public partial class NativeMethods 7 | { 8 | [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 9 | public static extern bool DuplicateTokenEx( 10 | IntPtr hExistingToken, 11 | uint dwDesiredAccess, 12 | SecurityAttributes lpTokenAttributes, 13 | SecurityImpersonationLevel impersonationLevel, 14 | TokenType tokenType, 15 | out IntPtr hNewToken); 16 | 17 | [DllImport("advapi32.dll", SetLastError = true)] 18 | public static extern bool SetTokenInformation( 19 | IntPtr hToken, 20 | TokenInformationClass tokenInformationClass, 21 | ref uint TokenInformation, 22 | uint TokenInformationLength); 23 | 24 | public enum TokenInformationClass 25 | { 26 | /// 27 | /// The buffer receives a TOKEN_USER structure that contains the user account of the token. 28 | /// 29 | TokenUser = 1, 30 | 31 | /// 32 | /// The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token. 33 | /// 34 | TokenGroups, 35 | 36 | /// 37 | /// The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token. 38 | /// 39 | TokenPrivileges, 40 | 41 | /// 42 | /// The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects. 43 | /// 44 | TokenOwner, 45 | 46 | /// 47 | /// The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects. 48 | /// 49 | TokenPrimaryGroup, 50 | 51 | /// 52 | /// The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects. 53 | /// 54 | TokenDefaultDacl, 55 | 56 | /// 57 | /// The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information. 58 | /// 59 | TokenSource, 60 | 61 | /// 62 | /// The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token. 63 | /// 64 | TokenType, 65 | 66 | /// 67 | /// The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails. 68 | /// 69 | TokenImpersonationLevel, 70 | 71 | /// 72 | /// The buffer receives a TOKEN_STATISTICS structure that contains various token statistics. 73 | /// 74 | TokenStatistics, 75 | 76 | /// 77 | /// The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token. 78 | /// 79 | TokenRestrictedSids, 80 | 81 | /// 82 | /// The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token. 83 | /// 84 | TokenSessionId, 85 | 86 | /// 87 | /// The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted SIDs, and the authentication ID associated with the token. 88 | /// 89 | TokenGroupsAndPrivileges, 90 | 91 | /// 92 | /// Reserved. 93 | /// 94 | TokenSessionReference, 95 | 96 | /// 97 | /// The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag. 98 | /// 99 | TokenSandBoxInert, 100 | 101 | /// 102 | /// Reserved. 103 | /// 104 | TokenAuditPolicy, 105 | 106 | /// 107 | /// The buffer receives a TOKEN_ORIGIN value. 108 | /// 109 | TokenOrigin, 110 | 111 | /// 112 | /// The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token. 113 | /// 114 | TokenElevationType, 115 | 116 | /// 117 | /// The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token. 118 | /// 119 | TokenLinkedToken, 120 | 121 | /// 122 | /// The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated. 123 | /// 124 | TokenElevation, 125 | 126 | /// 127 | /// The buffer receives a DWORD value that is nonzero if the token has ever been filtered. 128 | /// 129 | TokenHasRestrictions, 130 | 131 | /// 132 | /// The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token. 133 | /// 134 | TokenAccessInformation, 135 | 136 | /// 137 | /// The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token. 138 | /// 139 | TokenVirtualizationAllowed, 140 | 141 | /// 142 | /// The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token. 143 | /// 144 | TokenVirtualizationEnabled, 145 | 146 | /// 147 | /// The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level. 148 | /// 149 | TokenIntegrityLevel, 150 | 151 | /// 152 | /// The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set. 153 | /// 154 | TokenUIAccess, 155 | 156 | /// 157 | /// The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy. 158 | /// 159 | TokenMandatoryPolicy, 160 | 161 | /// 162 | /// The buffer receives the token's logon security identifier (SID). 163 | /// 164 | TokenLogonSid, 165 | 166 | /// 167 | /// The maximum value for this enumeration 168 | /// 169 | MaxTokenInfoClass 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/Enums.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | 5 | public partial class NativeMethods 6 | { 7 | [Flags] 8 | public enum LogonType 9 | { 10 | LOGON32_LOGON_INTERACTIVE = 2, 11 | LOGON32_LOGON_NETWORK = 3, 12 | LOGON32_LOGON_BATCH = 4, 13 | LOGON32_LOGON_SERVICE = 5, 14 | LOGON32_LOGON_UNLOCK = 7, 15 | LOGON32_LOGON_NETWORK_CLEARTEXT = 8, 16 | LOGON32_LOGON_NEW_CREDENTIALS = 9 17 | } 18 | 19 | [Flags] 20 | public enum LogonProvider 21 | { 22 | LOGON32_PROVIDER_DEFAULT = 0, 23 | LOGON32_PROVIDER_WINNT35, 24 | LOGON32_PROVIDER_WINNT40, 25 | LOGON32_PROVIDER_WINNT50 26 | } 27 | 28 | public enum SecurityImpersonationLevel 29 | { 30 | SecurityAnonymous = 0, 31 | SecurityIdentification = 1, 32 | SecurityImpersonation = 2, 33 | SecurityDelegation = 3 34 | } 35 | 36 | public enum TokenType 37 | { 38 | TokenPrimary = 1, 39 | TokenImpersonation = 2 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/GetCurrentThreadId.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System.Runtime.InteropServices; 4 | 5 | public partial class NativeMethods 6 | { 7 | [DllImport("kernel32.dll", SetLastError = true)] 8 | public static extern int GetCurrentThreadId(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/GetProcessWindowStation.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | public partial class NativeMethods 7 | { 8 | [DllImport("user32.dll", SetLastError = true)] 9 | public static extern IntPtr GetProcessWindowStation(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/GetThreadDesktop.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | public partial class NativeMethods 7 | { 8 | [DllImport("user32.dll", SetLastError = true)] 9 | public static extern IntPtr GetThreadDesktop(int dwThreadId); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/JobObjectHandle.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2011 Uhuru Software, Inc., All Rights Reserved 4 | // 5 | // Modified by Luke Bakken from the original. 6 | // ----------------------------------------------------------------------- 7 | 8 | namespace StartProcessLib.PInvoke 9 | { 10 | using System.Runtime.ConstrainedExecution; 11 | using System.Security.Permissions; 12 | using Microsoft.Win32.SafeHandles; 13 | 14 | public partial class NativeMethods 15 | { 16 | /// 17 | /// A safe handle for Job Object. 18 | /// 19 | [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] 20 | [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] 21 | public class JobObjectHandle : SafeHandleZeroOrMinusOneIsInvalid 22 | { 23 | /// 24 | /// Prevents a default instance of the class from being created. 25 | /// 26 | private JobObjectHandle() 27 | : base(true) 28 | { 29 | } 30 | 31 | /// 32 | /// When overridden in a derived class, executes the code required to free the handle. 33 | /// 34 | /// 35 | /// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it generates a releaseHandleFailed MDA Managed Debugging Assistant. 36 | /// 37 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 38 | protected override bool ReleaseHandle() 39 | { 40 | return NativeMethods.CloseHandle(handle); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/JobObjectInfoClass.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | public partial class NativeMethods 4 | { 5 | /// 6 | /// Used for calling the Win API 7 | /// 8 | public enum JobObjectInfoClass 9 | { 10 | /// 11 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_BASIC_ACCOUNTING_INFORMATION structure. 12 | /// 13 | JobObjectBasicAccountingInformation = 1, 14 | 15 | /// 16 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION structure. 17 | /// 18 | JobObjectBasicAndIoAccountingInformation = 8, 19 | 20 | /// 21 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_BASIC_LIMIT_INFORMATION structure. 22 | /// 23 | JobObjectBasicLimitInformation = 2, 24 | 25 | /// 26 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_BASIC_PROCESS_ID_LIST structure. 27 | /// 28 | JobObjectBasicProcessIdList = 3, 29 | 30 | /// 31 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_BASIC_UI_RESTRICTIONS structure. 32 | /// 33 | JobObjectBasicUIRestrictions = 4, 34 | 35 | /// 36 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure. 37 | /// 38 | JobObjectEndOfJobTimeInformation = 6, 39 | 40 | /// 41 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. 42 | /// 43 | JobObjectExtendedLimitInformation = 9, 44 | 45 | /// 46 | /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_ASSOCIATE_COMPLETION_PORT structure. 47 | /// 48 | JobObjectAssociateCompletionPortInformation = 7, 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/JobObjectMethods.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2011 Uhuru Software, Inc., All Rights Reserved 4 | // 5 | // Modified by Luke Bakken from the original. 6 | // ----------------------------------------------------------------------- 7 | 8 | namespace StartProcessLib.PInvoke 9 | { 10 | using System; 11 | using System.Runtime.InteropServices; 12 | 13 | public partial class NativeMethods 14 | { 15 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 16 | public static extern JobObjectHandle CreateJobObject(IntPtr lpJobAttributes, string lpName); 17 | 18 | [DllImport("kernel32.dll", SetLastError = true)] 19 | [return: MarshalAs(UnmanagedType.Bool)] 20 | public static extern bool IsProcessInJob(IntPtr Process, JobObjectHandle hJob, [MarshalAs(UnmanagedType.Bool)] out bool Result); 21 | 22 | [DllImport("kernel32.dll", SetLastError = true)] 23 | [return: MarshalAs(UnmanagedType.Bool)] 24 | public static extern bool SetInformationJobObject(JobObjectHandle hJob, JobObjectInfoClass JobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); 25 | 26 | [DllImport("kernel32.dll", SetLastError = true)] 27 | [return: MarshalAs(UnmanagedType.Bool)] 28 | public static extern bool QueryInformationJobObject(JobObjectHandle hJob, JobObjectInfoClass JobObjectInformationClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength, IntPtr lpReturnLength); 29 | 30 | [DllImport("kernel32.dll", SetLastError = true)] 31 | [return: MarshalAs(UnmanagedType.Bool)] 32 | public static extern bool AssignProcessToJobObject(JobObjectHandle hJob, IntPtr hProcess); 33 | 34 | [DllImport("kernel32.dll", SetLastError = true)] 35 | [return: MarshalAs(UnmanagedType.Bool)] 36 | public static extern bool TerminateJobObject(JobObjectHandle hJob, uint uExitCode); 37 | 38 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 39 | public static extern JobObjectHandle OpenJobObject(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/JobObjectStructs.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2011 Uhuru Software, Inc., All Rights Reserved 4 | // 5 | // Modified by Luke Bakken from the original. 6 | // ----------------------------------------------------------------------- 7 | 8 | namespace StartProcessLib.PInvoke 9 | { 10 | using System; 11 | using System.Runtime.InteropServices; 12 | 13 | public partial class NativeMethods 14 | { 15 | /// 16 | /// Contains basic and extended limit information for a job object. 17 | /// 18 | [StructLayout(LayoutKind.Sequential)] 19 | public struct JOBOBJECT_BASIC_LIMIT_INFORMATION 20 | { 21 | /// 22 | /// JOB_OBJECT_LIMIT_ACTIVE_PROCESS Windows API constant. 23 | /// 24 | public const uint JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 0x00000008; 25 | 26 | /// 27 | /// JOB_OBJECT_LIMIT_AFFINITY Windows API constant. 28 | /// 29 | public const uint JOB_OBJECT_LIMIT_AFFINITY = 0x00000010; 30 | 31 | /// 32 | /// JOB_OBJECT_LIMIT_BREAKAWAY_OK Windows API constant. 33 | /// 34 | public const uint JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x00000800; 35 | 36 | /// 37 | /// JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION Windows API constant. 38 | /// 39 | public const uint JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x00000400; 40 | 41 | /// 42 | /// JOB_OBJECT_LIMIT_JOB_MEMORY Windows API constant. 43 | /// 44 | public const uint JOB_OBJECT_LIMIT_JOB_MEMORY = 0x00000200; 45 | 46 | /// 47 | /// JOB_OBJECT_LIMIT_JOB_TIME Windows API constant. 48 | /// 49 | public const uint JOB_OBJECT_LIMIT_JOB_TIME = 0x00000004; 50 | 51 | /// 52 | /// JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE Windows API constant. 53 | /// 54 | public const uint JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000; 55 | 56 | /// 57 | /// JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME Windows API constant. 58 | /// 59 | public const uint JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME = 0x00000040; 60 | 61 | /// 62 | /// JOB_OBJECT_LIMIT_PRIORITY_CLASS Windows API constant. 63 | /// 64 | public const uint JOB_OBJECT_LIMIT_PRIORITY_CLASS = 0x00000020; 65 | 66 | /// 67 | /// JOB_OBJECT_LIMIT_PROCESS_MEMORY Windows API constant. 68 | /// 69 | public const uint JOB_OBJECT_LIMIT_PROCESS_MEMORY = 0x00000100; 70 | 71 | /// 72 | /// JOB_OBJECT_LIMIT_PROCESS_TIME Windows API constant. 73 | /// 74 | public const uint JOB_OBJECT_LIMIT_PROCESS_TIME = 0x00000002; 75 | 76 | /// 77 | /// JOB_OBJECT_LIMIT_SCHEDULING_CLASS Windows API constant. 78 | /// 79 | public const uint JOB_OBJECT_LIMIT_SCHEDULING_CLASS = 0x00000080; 80 | 81 | /// 82 | /// JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK Windows API constant. 83 | /// 84 | public const uint JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x00001000; 85 | 86 | /// 87 | /// JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK Windows API constant. 88 | /// 89 | public const uint JOB_OBJECT_LIMIT_SUBSET_AFFINITY = 0x00004000; 90 | 91 | /// 92 | /// JOB_OBJECT_LIMIT_WORKINGSET Windows API constant. 93 | /// 94 | public const uint JOB_OBJECT_LIMIT_WORKINGSET = 0x00000001; 95 | 96 | /// 97 | /// Per process user time limit. 98 | /// 99 | public long PerProcessUserTimeLimit; 100 | 101 | /// 102 | /// Per job user time limit. 103 | /// 104 | public long PerJobUserTimeLimit; 105 | 106 | /// 107 | /// Limit flags. 108 | /// 109 | public uint LimitFlags; 110 | 111 | /// 112 | /// Minimum working set size. 113 | /// 114 | public IntPtr MinimumWorkingSetSize; 115 | 116 | /// 117 | /// Maximum working set size. 118 | /// 119 | public IntPtr MaximumWorkingSetSize; 120 | 121 | /// 122 | /// Active process limit. 123 | /// 124 | public uint ActiveProcessLimit; 125 | 126 | /// 127 | /// Processor affinity. 128 | /// 129 | public IntPtr Affinity; 130 | 131 | /// 132 | /// Priority class. 133 | /// 134 | public uint PriorityClass; 135 | 136 | /// 137 | /// Scheduling class. 138 | /// 139 | public uint SchedulingClass; 140 | } 141 | 142 | /// 143 | /// JOBOBJECT_BASIC_UI_RESTRICTIONS Windows API structure. 144 | /// 145 | [StructLayout(LayoutKind.Sequential)] 146 | public struct JOBOBJECT_BASIC_UI_RESTRICTIONS 147 | { 148 | /// 149 | /// UI Restrictions class. 150 | /// 151 | public uint UIRestrictionsClass; 152 | } 153 | 154 | /// 155 | /// JOBOBJECT_CPU_RATE_CONTROL_INFORMATION Windows API structure. 156 | /// 157 | [StructLayout(LayoutKind.Sequential)] 158 | public struct JOBOBJECT_CPU_RATE_CONTROL_INFORMATION 159 | { 160 | /// 161 | /// Control Flags. 162 | /// 163 | public uint ControlFlags; 164 | 165 | /// 166 | /// CPU rate weight. 167 | /// 168 | public uint CpuRate_Weight; 169 | } 170 | 171 | /// 172 | /// JOBOBJECT_EXTENDED_LIMIT_INFORMATION Windows API structure. 173 | /// 174 | [StructLayout(LayoutKind.Sequential)] 175 | public struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION 176 | { 177 | /// 178 | /// BasicLimitInformation Windows API structure member. 179 | /// 180 | public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; 181 | 182 | /// 183 | /// IoInfo Windows API structure member. 184 | /// 185 | public IO_COUNTERS IoInfo; 186 | 187 | /// 188 | /// ProcessMemoryLimit Windows API structure member. 189 | /// 190 | public IntPtr ProcessMemoryLimit; 191 | 192 | /// 193 | /// JobMemoryLimit Windows API structure member. 194 | /// 195 | public IntPtr JobMemoryLimit; 196 | 197 | /// 198 | /// PeakProcessMemoryUsed Windows API structure member. 199 | /// 200 | public IntPtr PeakProcessMemoryUsed; 201 | 202 | /// 203 | /// PeakJobMemoryUsed Windows API structure member. 204 | /// 205 | public IntPtr PeakJobMemoryUsed; 206 | } 207 | 208 | /// 209 | /// IO_COUNTERS Windows API structure. 210 | /// 211 | [StructLayout(LayoutKind.Sequential)] 212 | public struct IO_COUNTERS 213 | { 214 | /// 215 | /// ReadOperationCount Windows API structure member. 216 | /// 217 | public ulong ReadOperationCount; 218 | 219 | /// 220 | /// WriteOperationCount Windows API structure member. 221 | /// 222 | public ulong WriteOperationCount; 223 | 224 | /// 225 | /// OtherOperationCount Windows API structure member. 226 | /// 227 | public ulong OtherOperationCount; 228 | 229 | /// 230 | /// ReadTransferCount Windows API structure member. 231 | /// 232 | public ulong ReadTransferCount; 233 | 234 | /// 235 | /// WriteTransferCount Windows API structure member. 236 | /// 237 | public ulong WriteTransferCount; 238 | 239 | /// 240 | /// OtherTransferCount Windows API structure member. 241 | /// 242 | public ulong OtherTransferCount; 243 | } 244 | 245 | /// 246 | /// JOBOBJECT_BASIC_ACCOUNTING_INFORMATION Windows API structure. 247 | /// 248 | [StructLayout(LayoutKind.Sequential)] 249 | public struct JOBOBJECT_BASIC_ACCOUNTING_INFORMATION 250 | { 251 | /// 252 | /// TotalUserTime Windows API structure member. 253 | /// 254 | public ulong TotalUserTime; 255 | 256 | /// 257 | /// TotalKernelTime Windows API structure member. 258 | /// 259 | public ulong TotalKernelTime; 260 | 261 | /// 262 | /// ThisPeriodTotalUserTime Windows API structure member. 263 | /// 264 | public ulong ThisPeriodTotalUserTime; 265 | 266 | /// 267 | /// ThisPeriodTotalKernelTime Windows API structure member. 268 | /// 269 | public ulong ThisPeriodTotalKernelTime; 270 | 271 | /// 272 | /// TotalPageFaultCount Windows API structure member. 273 | /// 274 | public uint TotalPageFaultCount; 275 | 276 | /// 277 | /// TotalProcesses Windows API structure member. 278 | /// 279 | public uint TotalProcesses; 280 | 281 | /// 282 | /// ActiveProcesses Windows API structure member. 283 | /// 284 | public uint ActiveProcesses; 285 | 286 | /// 287 | /// TotalTerminatedProcesses Windows API structure member. 288 | /// 289 | public uint TotalTerminatedProcesses; 290 | } 291 | 292 | /// 293 | /// JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION Windows API structure. 294 | /// 295 | public struct JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION 296 | { 297 | /// 298 | /// BasicInfo Windows API structure member. 299 | /// 300 | public JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo; 301 | 302 | /// 303 | /// IoInfo Windows API structure member. 304 | /// 305 | public IO_COUNTERS IoInfo; 306 | } 307 | 308 | /// 309 | /// JOBOBJECT_BASIC_PROCESS_ID_LIST Windows API structure. 310 | /// 311 | public struct JOBOBJECT_BASIC_PROCESS_ID_LIST 312 | { 313 | /// 314 | /// The maximum number of processes that are allocated when querying Windows API. 315 | /// 316 | public const uint MaxProcessListLength = 200; 317 | 318 | /// 319 | /// NumberOfAssignedProcesses Windows API structure member. 320 | /// 321 | public uint NumberOfAssignedProcesses; 322 | 323 | /// 324 | /// NumberOfProcessIdsInList Windows API structure member. 325 | /// 326 | public uint NumberOfProcessIdsInList; 327 | 328 | /// 329 | /// ProcessIdList Windows API structure member. 330 | /// 331 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)MaxProcessListLength)] 332 | public IntPtr[] ProcessIdList; 333 | } 334 | } 335 | } 336 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/LogonUser.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | public partial class NativeMethods 7 | { 8 | [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 9 | public static extern Boolean LogonUser( 10 | String lpszUserName, 11 | String lpszDomain, 12 | String lpszPassword, 13 | LogonType dwLogonType, 14 | LogonProvider dwLogonProvider, 15 | out IntPtr phToken); 16 | 17 | [DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)] 18 | public static extern bool LoadUserProfile(IntPtr hToken, ProfileInfo lpProfileInfo); 19 | 20 | [DllImport("userenv.dll", SetLastError=true, CharSet=CharSet.Auto)] 21 | public static extern bool UnloadUserProfile(IntPtr hToken, IntPtr hProfile); 22 | 23 | [StructLayout(LayoutKind.Sequential)] 24 | public class ProfileInfo 25 | { 26 | public Int32 dwSize; 27 | public Int32 dwFlags; 28 | 29 | [MarshalAs(UnmanagedType.LPTStr)] 30 | public String lpUserName; 31 | 32 | [MarshalAs(UnmanagedType.LPTStr)] 33 | public String lpProfilePath; 34 | 35 | [MarshalAs(UnmanagedType.LPTStr)] 36 | public String lpDefaultPath; 37 | 38 | [MarshalAs(UnmanagedType.LPTStr)] 39 | public String lpServerName; 40 | 41 | [MarshalAs(UnmanagedType.LPTStr)] 42 | public String lpPolicyPath; 43 | 44 | public IntPtr hProfile; 45 | 46 | public ProfileInfo() 47 | { 48 | this.dwSize = Marshal.SizeOf(this); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System.Security; 4 | 5 | [SuppressUnmanagedCodeSecurity] 6 | public partial class NativeMethods 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/RevertToSelf.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System.Runtime.InteropServices; 4 | 5 | public partial class NativeMethods 6 | { 7 | [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 8 | public static extern bool RevertToSelf(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/SafeUserTokenHandle.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using Microsoft.Win32.SafeHandles; 5 | 6 | internal sealed class SafeUserTokenHandle : SafeHandleZeroOrMinusOneIsInvalid 7 | { 8 | public SafeUserTokenHandle() : base(true) 9 | { 10 | } 11 | 12 | public SafeUserTokenHandle(IntPtr existingHandle) : base(true) 13 | { 14 | base.SetHandle(existingHandle); 15 | } 16 | 17 | public static explicit operator IntPtr(SafeUserTokenHandle userTokenHandle) 18 | { 19 | return userTokenHandle.DangerousGetHandle(); 20 | } 21 | 22 | protected override bool ReleaseHandle() 23 | { 24 | return NativeMethods.CloseHandle(this.handle); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/SecurityAttributes.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | public partial class NativeMethods 7 | { 8 | [StructLayout(LayoutKind.Sequential)] 9 | public class SecurityAttributes 10 | { 11 | public Int32 Length = 0; 12 | public IntPtr lpSecurityDescriptor = IntPtr.Zero; 13 | public bool bInheritHandle = false; 14 | 15 | public SecurityAttributes() 16 | { 17 | this.Length = Marshal.SizeOf(this); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /StartProcessLib/PInvoke/Utils.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessLib.PInvoke 2 | { 3 | using System; 4 | using System.ComponentModel; 5 | 6 | public static class Utils 7 | { 8 | public static IntPtr LogonAndGetPrimaryToken(string userName, string password) 9 | { 10 | IntPtr primaryToken = IntPtr.Zero; 11 | 12 | if (NativeMethods.RevertToSelf()) 13 | { 14 | if (NativeMethods.LogonUser(userName, ".", password, 15 | NativeMethods.LogonType.LOGON32_LOGON_INTERACTIVE, 16 | NativeMethods.LogonProvider.LOGON32_PROVIDER_DEFAULT, 17 | out primaryToken)) 18 | { 19 | return primaryToken; 20 | } 21 | else 22 | { 23 | throw new Win32Exception(); 24 | } 25 | } 26 | else 27 | { 28 | throw new Win32Exception(); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /StartProcessLib/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("StartProcessLib")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("StartProcessLib")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0d84c4ed-f318-4acf-b2be-69863e3f95aa")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /StartProcessLib/StartProcessLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3324447D-2457-404A-A1D8-B739C5150D2D} 8 | Library 9 | Properties 10 | StartProcessLib 11 | StartProcessLib 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | true 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | ..\lib\AsproLock.dll 61 | 62 | 63 | ..\packages\NLog.2.0.1.2\lib\net45\NLog.dll 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /StartProcessLib/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /StartProcessService/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /StartProcessService/Program.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessService 2 | { 3 | using System; 4 | using System.IO; 5 | using NLog; 6 | using Topshelf; 7 | 8 | class Program 9 | { 10 | const string DisplayName = "StartProcessService"; 11 | const string ServiceName = "StartProcessService"; 12 | 13 | static readonly Logger log = LogManager.GetCurrentClassLogger(); 14 | 15 | static void Main(string[] args) 16 | { 17 | Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); 18 | 19 | log.Info("Current directory is: '{0}'", Directory.GetCurrentDirectory()); 20 | 21 | HostFactory.Run(x => 22 | { 23 | x.Service(); 24 | x.SetDescription(DisplayName); 25 | x.SetDisplayName(DisplayName); 26 | x.SetServiceName(ServiceName); 27 | x.StartAutomatically(); 28 | x.RunAsLocalSystem(); 29 | x.UseNLog(); 30 | }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /StartProcessService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("StartProcessService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("StartProcessService")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("86a3003a-3df4-48ec-bab7-48adee219d7a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /StartProcessService/StartProcessService.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8E1DF9CB-D053-4A2F-826D-FAE2BDBDC139} 8 | Exe 9 | Properties 10 | StartProcessService 11 | StartProcessService 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Designer 42 | 43 | 44 | 45 | 46 | 47 | {3324447d-2457-404a-a1d8-b739c5150d2d} 48 | StartProcessLib 49 | 50 | 51 | 52 | 53 | ..\packages\NLog.2.0.1.2\lib\net45\NLog.dll 54 | 55 | 56 | 57 | ..\packages\Topshelf.3.1.1\lib\net40-full\Topshelf.dll 58 | 59 | 60 | ..\packages\Topshelf.NLog.3.1.1\lib\net40-full\Topshelf.NLog.dll 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /StartProcessService/WinService.cs: -------------------------------------------------------------------------------- 1 | namespace StartProcessService 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.IO; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using NLog; 11 | using StartProcessLib; 12 | using StartProcessLib.PInvoke; 13 | using Topshelf; 14 | 15 | public class WinService : ServiceControl 16 | { 17 | const string testPowershellScript = @" 18 | $now = Get-Date 19 | $sleepSeconds = Get-Random -Minimum 30 -Maximum 300 20 | Add-Content -Path C:\tmp\test.txt -Value ""Hello from $pid the time is $now - sleeping for $sleepSeconds seconds..."" 21 | Start-Sleep -s $sleepSeconds 22 | $now = Get-Date 23 | Add-Content -Path C:\tmp\test.txt -Value ""Hello from $pid the time is $now"" 24 | "; 25 | const string workingDir = @"C:\tmp"; 26 | // create with 'net user test_user password /add' 27 | const string userName = "test_user"; 28 | const string password = "Pass@word1"; 29 | 30 | private readonly Logger log = LogManager.GetCurrentClassLogger(); 31 | private readonly CancellationTokenSource cts = new CancellationTokenSource(); 32 | private readonly CancellationToken ct; 33 | 34 | private Task serviceTask; 35 | 36 | public WinService() 37 | { 38 | this.ct = cts.Token; 39 | } 40 | 41 | public bool Start(HostControl hostControl) 42 | { 43 | serviceTask = Task.Run((Action)ServiceMain, ct); 44 | return true; 45 | } 46 | 47 | public bool Stop(HostControl hostControl) 48 | { 49 | try 50 | { 51 | cts.Cancel(); 52 | Task.WaitAll(new[] { serviceTask }, TimeSpan.FromSeconds(25)); 53 | } 54 | catch (Exception ex) 55 | { 56 | log.InfoException("Exception(s) during Stop.", ex); 57 | } 58 | return true; 59 | } 60 | 61 | private void ServiceMain() 62 | { 63 | const string testFile = @"C:\tmp\test-it.ps1"; 64 | File.Delete(testFile); 65 | File.WriteAllText(testFile, testPowershellScript); 66 | 67 | var permissionManager = new DesktopPermissionManager(userName); 68 | 69 | var startupInfo = new NativeMethods.StartupInfo(); 70 | string lpApplicationName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; 71 | var cmdLine = new StringBuilder(1024); 72 | cmdLine.AppendFormat(@" -InputFormat None -NoLogo -NoProfile -NonInteractive -File {0}", testFile); 73 | 74 | permissionManager.AddDesktopPermission(); 75 | 76 | using (var jobObject = new JobObject("StartProcessServiceJobObject")) 77 | { 78 | jobObject.KillProcessesOnJobClose = true; 79 | 80 | while (!ct.IsCancellationRequested) 81 | { 82 | try 83 | { 84 | log.Debug("Executing command: '{0}'", cmdLine); 85 | 86 | // Now create the process as the user 87 | NativeMethods.ProcessInformation pi; 88 | 89 | var saProcessAttributes = new NativeMethods.SecurityAttributes(); 90 | var saThreadAttributes = new NativeMethods.SecurityAttributes(); 91 | 92 | var createProcessFlags = 93 | NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW | 94 | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; 95 | 96 | IntPtr primaryToken = Utils.LogonAndGetPrimaryToken(userName, password); 97 | 98 | if (NativeMethods.CreateProcessAsUser(primaryToken, 99 | lpApplicationName, 100 | cmdLine, 101 | saProcessAttributes, 102 | saThreadAttributes, 103 | false, 104 | createProcessFlags, 105 | IntPtr.Zero, 106 | workingDir, 107 | startupInfo, 108 | out pi)) 109 | { 110 | log.Debug("created process: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); 111 | jobObject.AddProcess(pi.hProcess); 112 | log.Debug("job object has '{0}' processes in it.", jobObject.GetJobProcesses().Count()); 113 | NativeMethods.CloseHandle(pi.hProcess); 114 | NativeMethods.CloseHandle(pi.hThread); 115 | } 116 | else 117 | { 118 | int err = Marshal.GetLastWin32Error(); 119 | log.Error("Error '{0}' creating process.", err); 120 | } 121 | } 122 | catch (Exception ex) 123 | { 124 | log.ErrorException("Exception creating process.", ex); 125 | } 126 | finally 127 | { 128 | Thread.Sleep(TimeSpan.FromSeconds(10)); 129 | } 130 | } 131 | } 132 | 133 | permissionManager.RemoveDesktopPermission(); 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /StartProcessService/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/AsproLock.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebakken/windows-processes/40fe6379a37666edf7fdb95276573b1ee2520696/lib/AsproLock.dll -------------------------------------------------------------------------------- /lib/AsproLock.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebakken/windows-processes/40fe6379a37666edf7fdb95276573b1ee2520696/lib/AsproLock.pdb -------------------------------------------------------------------------------- /lib/AsproLock.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AsproLock 5 | 6 | 7 | 8 | 9 | The base class for all security objects. 10 | 11 | 12 | 13 | 14 | Persists the changes made to the security object. Must be overridden for 15 | custom security objects. 16 | 17 | 18 | 19 | 20 | Gets the access control sections that have been changed. 21 | 22 | 23 | 24 | 25 | 26 | Resets the sections changed flags. 27 | 28 | 29 | 30 | 31 | Gets the generic mapping associated with the securable object. 32 | 33 | A associated with this security 34 | object type. 35 | 36 | 37 | 38 | Gets a bitmask representing the maximum access allowed to this 39 | securable object. 40 | 41 | The handle to the token for which the 42 | access is being calculated. This must be an impersonation token. 43 | An containing the bitmask of the access 44 | rights that have been granted to the user represented by the token. 45 | 46 | 47 | 48 | Determines whether the user represented by the specified token handle 49 | has been granted access to this securable object. 50 | 51 | The handle to the token for which the 52 | access is being verified. This must be an impersonation token. 53 | The desired access. 54 | 55 | true if the desired access is allowed; otherwise, false. 56 | 57 | 58 | 59 | 60 | Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 61 | 62 | 63 | 64 | Represents a set of DesktopRights allowed or denied 65 | for a user or group. This class cannot be inherited. 66 | 67 | 68 | 69 | Initializes a new instance of the class. 70 | 71 | The identity of the user to be granted or denied 72 | the associated rights. 73 | The desktop rights allowed or denied. 74 | The type of access controlled by the rule. 75 | 76 | 77 | 78 | Initializes a new instance of the class. 79 | 80 | The identity of the user to be granted or denied 81 | the associated rights. 82 | The desktop rights allowed or denied. 83 | The type of access controlled by the rule. 84 | 85 | 86 | 87 | Gets the desktop rights associated with this rule. 88 | 89 | The combination of values that defines 90 | the rights associated with this rule. 91 | 92 | 93 | Represents a set of DesktopRights to be audited 94 | for a user or group. This class cannot be inherited. 95 | 96 | 97 | 98 | Initializes a new instance of the class. 99 | 100 | The identity. 101 | The desktop rights. 102 | The type. 103 | 104 | 105 | 106 | Initializes a new instance of the class. 107 | 108 | The identity. 109 | The desktop rights. 110 | The type. 111 | 112 | 113 | 114 | Gets the desktop rights associated with this rule. 115 | 116 | The combination of values that defines 117 | the rights associated with this rule. 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | f 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | Initializes a new instance of the class. 217 | 218 | 219 | 220 | 221 | Initializes a new instance of the class. 222 | 223 | Name of the desktop. 224 | The sections requested. 225 | 226 | 227 | 228 | Initializes a new instance of the class. 229 | 230 | The desktop handle. 231 | The sections requested. 232 | 233 | 234 | 235 | Initializes a new instance of the class with the specified values. 236 | 237 | The identity to which the access rule applies. It must be an object that can be cast as a . 238 | The access mask of this rule. The access mask is a 32-bit collection of anonymous bits, the meaning of which is defined by the individual integrators. 239 | true if this rule is inherited from a parent container. 240 | Specifies the inheritance properties of the access rule. 241 | Specifies whether inherited access rules are automatically propagated. The propagation flags are ignored if is set to . 242 | Specifies the valid access control type. 243 | 244 | The object that this method creates. 245 | 246 | 247 | 248 | 249 | Initializes a new instance of the class with the specified values. 250 | 251 | The identity to which the audit rule applies. It must be an object that can be cast as a . 252 | The access mask of this rule. The access mask is a 32-bit collection of anonymous bits, the meaning of which is defined by the individual integrators. 253 | true if this rule is inherited from a parent container. 254 | Specifies the inheritance properties of the audit rule. 255 | Specifies whether inherited audit rules are automatically propagated. The propagation flags are ignored if is set to . 256 | Specifies the conditions for which the rule is audited. 257 | 258 | The object that this method creates. 259 | 260 | 261 | 262 | 263 | Adds the access rule. 264 | 265 | The access rule. 266 | 267 | 268 | 269 | Adds the audit rule. 270 | 271 | The audit rule. 272 | 273 | 274 | 275 | Removes the access rule. 276 | 277 | The access rule. 278 | 279 | 280 | 281 | 282 | Removes the access rule all. 283 | 284 | The access rule. 285 | 286 | 287 | 288 | Removes the access rule specific. 289 | 290 | The access rule. 291 | 292 | 293 | 294 | Removes the audit rule. 295 | 296 | The audit rule. 297 | 298 | 299 | 300 | 301 | Removes the audit rule all. 302 | 303 | The audit rule. 304 | 305 | 306 | 307 | Removes the audit rule specific. 308 | 309 | The audit rule. 310 | 311 | 312 | 313 | Resets the access rule. 314 | 315 | The access rule. 316 | 317 | 318 | 319 | Sets the access rule. 320 | 321 | The access rule. 322 | 323 | 324 | 325 | Sets the audit rule. 326 | 327 | The audit rule. 328 | 329 | 330 | 331 | Gets the of the securable object associated with this object. 332 | 333 | 334 | 335 | The type of the securable object associated with this object. 336 | 337 | 338 | 339 | 340 | Gets the of the object associated with the access rules of this object. The object must be an object that can be cast as a object. 341 | 342 | 343 | 344 | The type of the object associated with the access rules of this object. 345 | 346 | 347 | 348 | 349 | Gets the object associated with the audit rules of this object. The object must be an object that can be cast as a object. 350 | 351 | 352 | 353 | The type of the object associated with the audit rules of this object. 354 | 355 | 356 | 357 | Represents a set of DirectoryAccessRights rights allowed or denied 358 | for a user or group. This class cannot be inherited. 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | Initializes a new instance of the class. 369 | 370 | The identity. 371 | The directory rights. 372 | The type. 373 | 374 | 375 | 376 | Initializes a new instance of the class. 377 | 378 | The identity. 379 | The directory rights. 380 | The type. 381 | 382 | 383 | 384 | Gets the directory rights associated with this rule. 385 | 386 | The combination of values that defines 387 | the rights associated with this rule. 388 | 389 | 390 | Represents a set of FileAccessRights rights allowed or denied 391 | for a user or group. This class cannot be inherited. 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | Initializes a new instance of the class. 402 | 403 | The identity. 404 | The file rights. 405 | The type. 406 | 407 | 408 | 409 | Initializes a new instance of the class. 410 | 411 | The identity. 412 | The file rights. 413 | The type. 414 | 415 | 416 | 417 | Gets the file rights associated with this rule. 418 | 419 | The combination of values that defines 420 | the rights associated with this rule. 421 | 422 | 423 | Represents a set of FileMappingAccessRights rights allowed or denied 424 | for a user or group. This class cannot be inherited. 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | Initializes a new instance of the class. 435 | 436 | The identity. 437 | The file mapping rights. 438 | The type. 439 | 440 | 441 | 442 | Initializes a new instance of the class. 443 | 444 | The identity. 445 | The file mapping rights. 446 | The type. 447 | 448 | 449 | 450 | Gets the file mapping rights associated with this rule. 451 | 452 | The combination of values that defines 453 | the rights associated with this rule. 454 | 455 | 456 | Represents a set of JobObjectAccessRights rights allowed or denied 457 | for a user or group. This class cannot be inherited. 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | Initializes a new instance of the class. 468 | 469 | The identity. 470 | The job object rights. 471 | The type. 472 | 473 | 474 | 475 | Initializes a new instance of the class. 476 | 477 | The identity. 478 | The job object rights. 479 | The type. 480 | 481 | 482 | 483 | Gets the job object rights associated with this rule. 484 | 485 | The combination of values that defines 486 | the rights associated with this rule. 487 | 488 | 489 | Represents a set of PipeAccessRights rights allowed or denied 490 | for a user or group. This class cannot be inherited. 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | Initializes a new instance of the class. 501 | 502 | The identity. 503 | The pipe rights. 504 | The type. 505 | 506 | 507 | 508 | Initializes a new instance of the class. 509 | 510 | The identity. 511 | The pipe rights. 512 | The type. 513 | 514 | 515 | 516 | Gets the pipe rights associated with this rule. 517 | 518 | The combination of values that defines 519 | the rights associated with this rule. 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | Initializes a new instance of the class. 529 | 530 | The identity. 531 | The service rights. 532 | The type. 533 | 534 | 535 | 536 | Initializes a new instance of the class. 537 | 538 | The identity. 539 | The service rights. 540 | The type. 541 | 542 | 543 | 544 | Gets the printer rights associated with this rule. 545 | 546 | The combination of values that defines 547 | the rights associated with this rule. 548 | 549 | 550 | Represents a set of FileMappingAccessRights rights allowed or denied 551 | for a user or group. This class cannot be inherited. 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | Initializes a new instance of the class. 562 | 563 | The identity. 564 | The process rights. 565 | The type. 566 | 567 | 568 | 569 | Initializes a new instance of the class. 570 | 571 | The identity. 572 | The process rights. 573 | The type. 574 | 575 | 576 | 577 | Gets the process rights associated with this rule. 578 | 579 | The combination of values that defines 580 | the rights associated with this rule. 581 | 582 | 583 | Represents a set of RegistryKeyAccessRights rights allowed or denied 584 | for a user or group. This class cannot be inherited. 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | Initializes a new instance of the class. 595 | 596 | The identity. 597 | The registry key rights. 598 | The type. 599 | 600 | 601 | 602 | Initializes a new instance of the class. 603 | 604 | The identity. 605 | The registry key rights. 606 | The type. 607 | 608 | 609 | 610 | Gets the registry key rights associated with this rule. 611 | 612 | The combination of values that defines 613 | the rights associated with this rule. 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | Initializes a new instance of the class. 623 | 624 | The identity. 625 | The service rights. 626 | The type. 627 | 628 | 629 | 630 | Initializes a new instance of the class. 631 | 632 | The identity. 633 | The service rights. 634 | The type. 635 | 636 | 637 | 638 | Gets the service rights associated with this rule. 639 | 640 | The combination of values that defines 641 | the rights associated with this rule. 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | Initializes a new instance of the class. 651 | 652 | The identity. 653 | The share rights. 654 | The type. 655 | 656 | 657 | 658 | Initializes a new instance of the class. 659 | 660 | The identity. 661 | The share rights. 662 | The type. 663 | 664 | 665 | 666 | Gets the share rights associated with this rule. 667 | 668 | The combination of values that defines 669 | the rights associated with this rule. 670 | 671 | 672 | Represents a set of FileMappingAccessRights rights allowed or denied 673 | for a user or group. This class cannot be inherited. 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | Initializes a new instance of the class. 684 | 685 | The identity. 686 | The thread rights. 687 | The type. 688 | 689 | 690 | 691 | Initializes a new instance of the class. 692 | 693 | The identity. 694 | The thread rights. 695 | The type. 696 | 697 | 698 | 699 | Gets the thread rights associated with this rule. 700 | 701 | The combination of values that defines 702 | the rights associated with this rule. 703 | 704 | 705 | Represents a set of TokenAccessRights rights allowed or denied 706 | for a user or group. This class cannot be inherited. 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | Initializes a new instance of the class. 717 | 718 | The identity. 719 | The token rights. 720 | The type. 721 | 722 | 723 | 724 | Initializes a new instance of the class. 725 | 726 | The identity. 727 | The token rights. 728 | The type. 729 | 730 | 731 | 732 | Gets the token rights associated with this rule. 733 | 734 | The combination of values that defines 735 | the rights associated with this rule. 736 | 737 | 738 | Represents a set of WaitObjectAccessRights rights allowed or denied 739 | for a user or group. This class cannot be inherited. 740 | 741 | 742 | 743 | 744 | Initializes a new instance of the class. 745 | 746 | The identity. 747 | The wait object rights. 748 | The type. 749 | 750 | 751 | 752 | Initializes a new instance of the class. 753 | 754 | The identity. 755 | The wait object rights. 756 | The type. 757 | 758 | 759 | 760 | Gets the wait object rights associated with this rule. 761 | 762 | The combination of values that defines 763 | the rights associated with this rule. 764 | 765 | 766 | Represents a set of WindowStationAccessRights rights allowed or denied 767 | for a user or group. This class cannot be inherited. 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | Initializes a new instance of the class. 778 | 779 | The identity. 780 | The window station rights. 781 | The type. 782 | 783 | 784 | 785 | Initializes a new instance of the class. 786 | 787 | The identity. 788 | The window station rights. 789 | The type. 790 | 791 | 792 | 793 | Gets the window station rights associated with this rule. 794 | 795 | The combination of values that defines 796 | the rights associated with this rule. 797 | 798 | 799 | 800 | -------------------------------------------------------------------------------- /licenses/asprosys.txt: -------------------------------------------------------------------------------- 1 | http://www.asprosys.com/Resources/Samples/codesamples.aspx 2 | http://asprosys.blogspot.com/2009/03/perils-and-pitfalls-of-launching.html 3 | 4 | Code Samples for Developers 5 | 6 | All code samples linked from here are put in the public domain unless 7 | explicitly licensed differently in the source code itself. You may use them 8 | however you wish but we would appreciate proper attribution, please do not pass 9 | these off as your own work. The code is provided "AS IS" it carries no 10 | guarantees at all. 11 | -------------------------------------------------------------------------------- /licenses/uhuru_software.txt: -------------------------------------------------------------------------------- 1 | https://github.com/UhuruSoftware/vcap-dotnet 2 | https://github.com/UhuruSoftware/vcap-dotnet/blob/master/license.txt 3 | 4 | Copyright [2011] [Uhuru Software, Inc.] 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 21 | EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | IN THE SOFTWARE. 25 | --------------------------------------------------------------------------------