@@ -154,16 +154,136 @@ public static NtJob Open(string path, NtObject root)
154154 {
155155 return Open ( path , root , JobAccessRights . MaximumAllowed ) ;
156156 }
157+
158+ /// <summary>
159+ /// Create and initialize a Silo,
160+ /// </summary>
161+ /// <param name="root_dir_flags">Flags for root directory.</param>
162+ /// <param name="throw_on_error">True to throw on error.</param>
163+ /// <returns>The Job object.</returns>
164+ public static NtResult < NtJob > CreateSilo ( SiloObjectRootDirectoryControlFlags root_dir_flags , bool throw_on_error )
165+ {
166+ using ( var job = Create ( null , JobAccessRights . MaximumAllowed , throw_on_error ) )
167+ {
168+ if ( ! job . IsSuccess )
169+ return job ;
170+ return job . Result . InitializeSilo ( root_dir_flags , false ) . CreateResult ( throw_on_error , ( ) => job . Result . Duplicate ( ) ) ;
171+ }
172+ }
173+
174+ /// <summary>
175+ /// Create an initialize a Silo,
176+ /// </summary>
177+ /// <param name="root_dir_flags">Flags for root directory.</param>
178+ /// <returns>The Job object.</returns>
179+ public static NtJob CreateSilo ( SiloObjectRootDirectoryControlFlags root_dir_flags )
180+ {
181+ return CreateSilo ( root_dir_flags , true ) . Result ;
182+ }
183+
157184 #endregion
158185
159186 #region Public Methods
187+ /// <summary>
188+ /// Convert Job object into a Silo
189+ /// </summary>
190+ /// <param name="throw_on_error">True to throw on error.</param>
191+ /// <returns>The NT status code.</returns>
192+ public NtStatus CreateSilo ( bool throw_on_error )
193+ {
194+ return NtSystemCalls . NtSetInformationJobObject ( Handle , JobObjectInformationClass . JobObjectCreateSilo ,
195+ SafeHGlobalBuffer . Null , 0 ) . ToNtException ( throw_on_error ) ;
196+ }
197+
160198 /// <summary>
161199 /// Convert Job object into a Silo
162200 /// </summary>
163201 public void CreateSilo ( )
164202 {
165- NtSystemCalls . NtSetInformationJobObject ( Handle , JobObjectInformationClass . JobObjectCreateSilo ,
166- SafeHGlobalBuffer . Null , 0 ) . ToNtException ( ) ;
203+ CreateSilo ( true ) ;
204+ }
205+
206+ /// <summary>
207+ /// Initialize a Silo,
208+ /// </summary>
209+ /// <param name="root_dir_flags">Flags for root directory.</param>
210+ /// <param name="throw_on_error">True to throw on error.</param>
211+ /// <returns>The NT status code.</returns>
212+ public NtStatus InitializeSilo ( SiloObjectRootDirectoryControlFlags root_dir_flags , bool throw_on_error )
213+ {
214+ NtStatus status = SetLimitFlags ( JobObjectLimitFlags . Application , throw_on_error ) ;
215+ if ( ! status . IsSuccess ( ) )
216+ return status ;
217+ status = CreateSilo ( throw_on_error ) ;
218+ if ( ! status . IsSuccess ( ) )
219+ return status ;
220+ status = AssignProcessPseudoHandle ( throw_on_error ) ;
221+ if ( ! status . IsSuccess ( ) )
222+ return status ;
223+ return SetSiloObjectRootDirectory ( root_dir_flags , throw_on_error ) ;
224+ }
225+
226+ /// <summary>
227+ /// Initialize a Silo,
228+ /// </summary>
229+ /// <param name="root_dir_flags">Flags for root directory.</param>
230+ public void InitializeSilo ( SiloObjectRootDirectoryControlFlags root_dir_flags )
231+ {
232+ InitializeSilo ( root_dir_flags , true ) ;
233+ }
234+
235+ /// <summary>
236+ /// Initialize a Silo to a Server Silo.
237+ /// </summary>
238+ /// <param name="delete_event">Event to signal when silo deleted.</param>
239+ /// <param name="downlevel_container">True if a downlevel container.</param>
240+ /// <param name="throw_on_error">True to throw on error.</param>
241+ /// <returns>The NT status code.</returns>
242+ public NtStatus InitializeServerSilo ( NtEvent delete_event , bool downlevel_container , bool throw_on_error )
243+ {
244+ ServerSiloInitInformation init = new ServerSiloInitInformation ( )
245+ {
246+ DeleteEvent = delete_event ? . Handle . DangerousGetHandle ( ) ?? IntPtr . Zero ,
247+ IsDownlevelContainer = downlevel_container
248+ } ;
249+
250+ return Set ( JobObjectInformationClass . JobObjectServerSiloInitialize , init , throw_on_error ) ;
251+ }
252+
253+ /// <summary>
254+ /// Initialize a Silo to a Server Silo.
255+ /// </summary>
256+ /// <param name="delete_event">Event to signal when silo deleted.</param>
257+ /// <param name="downlevel_container">True if a downlevel container.</param>
258+ /// <returns>The NT status code.</returns>
259+ public void InitializeServerSilo ( NtEvent delete_event , bool downlevel_container )
260+ {
261+ InitializeServerSilo ( delete_event , downlevel_container , true ) ;
262+ }
263+
264+ /// <summary>
265+ /// Create the silo's root object directory.
266+ /// </summary>
267+ /// <param name="flags">The flags for the creation.</param>
268+ /// <param name="throw_on_error">True to throw on error.</param>
269+ /// <returns>The NT status code.</returns>
270+ public NtStatus SetSiloObjectRootDirectory ( SiloObjectRootDirectoryControlFlags flags , bool throw_on_error )
271+ {
272+ SiloObjectRootDirectory root_dir = new SiloObjectRootDirectory
273+ {
274+ ControlFlags = flags
275+ } ;
276+ return Set ( JobObjectInformationClass . JobObjectSiloRootDirectory , root_dir , throw_on_error ) ;
277+ }
278+
279+ /// <summary>
280+ /// Create the silo's root object directory.
281+ /// </summary>
282+ /// <param name="flags">The flags for the creation.</param>
283+ /// <returns>The NT status code.</returns>
284+ public void SetSiloObjectRootDirectory ( SiloObjectRootDirectoryControlFlags flags )
285+ {
286+ SetSiloObjectRootDirectory ( flags , true ) ;
167287 }
168288
169289 /// <summary>
@@ -186,12 +306,20 @@ public NtStatus AssignProcess(NtProcess process, bool throw_on_error)
186306 return NtSystemCalls . NtAssignProcessToJobObject ( Handle , process . Handle ) . ToNtException ( throw_on_error ) ;
187307 }
188308
309+ /// <summary>
310+ /// Assign a process to this job object using current Job on Windows 1709+.
311+ /// </summary>
312+ public NtStatus AssignProcessPseudoHandle ( bool throw_on_error )
313+ {
314+ return AssignProcess ( NtProcess . FromHandle ( new SafeKernelObjectHandle ( new IntPtr ( - 7 ) , false ) ) , throw_on_error ) ;
315+ }
316+
189317 /// <summary>
190318 /// Assign a process to this job object using current Job on Windows 1709+.
191319 /// </summary>
192320 public void AssignProcessPseudoHandle ( )
193321 {
194- AssignProcess ( NtProcess . FromHandle ( new SafeKernelObjectHandle ( new IntPtr ( - 7 ) , false ) ) ) ;
322+ AssignProcessPseudoHandle ( true ) ;
195323 }
196324
197325 /// <summary>
@@ -529,6 +657,20 @@ public void SetUiRestrictionFlags(JobObjectUiLimitFlags flags)
529657 SetUiRestrictionFlags ( flags , true ) ;
530658 }
531659
660+ /// <summary>
661+ /// Query Silo Root directory.
662+ /// </summary>
663+ /// <param name="throw_on_error">True to throw on error.</param>
664+ /// <returns>The silo root directory.</returns>
665+ public NtResult < string > QuerySiloRootDirectory ( bool throw_on_error )
666+ {
667+ using ( var buffer = new SafeStructureInOutBuffer < SiloObjectRootDirectory > ( 64 * 1024 , true ) )
668+ {
669+ return QueryInformation ( JobObjectInformationClass . JobObjectSiloRootDirectory ,
670+ buffer , out int length ) . CreateResult ( throw_on_error , ( ) => buffer . Result . Path . ToString ( ) ) ;
671+ }
672+ }
673+
532674 /// <summary>
533675 /// Method to query information for this object type.
534676 /// </summary>
@@ -742,6 +884,21 @@ public bool SilentBreakawayOk
742884 /// </summary>
743885 public int JobId => Query < JobObjectContainerIdentifierV2 > ( JobObjectInformationClass . JobObjectContainerId ) . JobId ;
744886
887+ /// <summary>
888+ /// Get the Silo's Root Directory.
889+ /// </summary>
890+ public string SiloRootDirectory => QuerySiloRootDirectory ( true ) . GetResultOrDefault ( string . Empty ) ;
891+
892+ /// <summary>
893+ /// Get Silo basic information.
894+ /// </summary>
895+ public SiloObjectBasicInformation SiloBasicInformation => Query < SiloObjectBasicInformation > ( JobObjectInformationClass . JobObjectSiloBasicInformation ) ;
896+
897+ /// <summary>
898+ /// Get Silo basic information.
899+ /// </summary>
900+ public ServerSiloBasicInformation ServerSiloBasicInformation => Query < ServerSiloBasicInformation > ( JobObjectInformationClass . JobObjectServerSiloBasicInformation ) ;
901+
745902 #endregion
746903
747904 #region Private Members
0 commit comments