@@ -181,6 +181,66 @@ public static NtJob CreateSilo(SiloObjectRootDirectoryControlFlags root_dir_flag
181181 return CreateSilo ( root_dir_flags , true ) . Result ;
182182 }
183183
184+ /// <summary>
185+ /// Create and initialize a Server Silo,
186+ /// </summary>
187+ /// <param name="root_dir_flags">Flags for root directory.</param>
188+ /// <param name="throw_on_error">True to throw on error.</param>
189+ /// <param name="system_root">Path to the system root.</param>
190+ /// <param name="delete_event">Event to signal when silo deleted.</param>
191+ /// <param name="downlevel_container">True if a downlevel container.</param>
192+ /// <returns>The Job object.</returns>
193+ public static NtResult < NtJob > CreateServerSilo ( SiloObjectRootDirectoryControlFlags root_dir_flags , string system_root , NtEvent delete_event , bool downlevel_container , bool throw_on_error )
194+ {
195+ using ( var job = CreateSilo ( root_dir_flags , throw_on_error ) )
196+ {
197+ if ( ! job . IsSuccess )
198+ return job ;
199+
200+ NtStatus status = job . Result . SetSiloSystemRoot ( system_root , throw_on_error ) ;
201+ if ( ! status . IsSuccess ( ) )
202+ return status . CreateResultFromError < NtJob > ( throw_on_error ) ;
203+
204+ var silo_dir = job . Result . QuerySiloRootDirectory ( throw_on_error ) ;
205+ if ( ! silo_dir . IsSuccess )
206+ return silo_dir . Cast < NtJob > ( ) ;
207+
208+ string device_path = $@ "{ silo_dir . Result } \Device";
209+
210+ using ( var device_dir = NtDirectory . Open ( @"\Device" , null , DirectoryAccessRights . MaximumAllowed , throw_on_error ) )
211+ {
212+ if ( ! device_dir . IsSuccess )
213+ return device_dir . Cast < NtJob > ( ) ;
214+ using ( var obja = new ObjectAttributes ( device_path , AttributeFlags . CaseInsensitive | AttributeFlags . Permanent | AttributeFlags . OpenIf ) )
215+ {
216+ using ( var dir = NtDirectory . Create ( obja , DirectoryAccessRights . MaximumAllowed , device_dir . Result , throw_on_error ) )
217+ {
218+ if ( ! dir . IsSuccess )
219+ return dir . Cast < NtJob > ( ) ;
220+ }
221+ }
222+ }
223+
224+ status = job . Result . InitializeServerSilo ( delete_event , downlevel_container , throw_on_error ) ;
225+ if ( ! status . IsSuccess ( ) )
226+ return status . CreateResultFromError < NtJob > ( throw_on_error ) ;
227+ return job . Result . Duplicate ( ) . CreateResult ( ) ;
228+ }
229+ }
230+
231+ /// <summary>
232+ /// Create and initialize a Server Silo,
233+ /// </summary>
234+ /// <param name="root_dir_flags">Flags for root directory.</param>
235+ /// <param name="system_root">Path to the system root.</param>
236+ /// <param name="delete_event">Event to signal when silo deleted.</param>
237+ /// <param name="downlevel_container">True if a downlevel container.</param>
238+ /// <returns>The Job object.</returns>
239+ public static NtJob CreateServerSilo ( SiloObjectRootDirectoryControlFlags root_dir_flags , string system_root , NtEvent delete_event , bool downlevel_container )
240+ {
241+ return CreateServerSilo ( root_dir_flags , system_root , delete_event , downlevel_container , true ) . Result ;
242+ }
243+
184244 #endregion
185245
186246 #region Public Methods
@@ -239,6 +299,7 @@ public void InitializeSilo(SiloObjectRootDirectoryControlFlags root_dir_flags)
239299 /// <param name="downlevel_container">True if a downlevel container.</param>
240300 /// <param name="throw_on_error">True to throw on error.</param>
241301 /// <returns>The NT status code.</returns>
302+ /// <remarks>You must have set a system root and added a \Device directory (which shadows the real directory) to the silo object directory.</remarks>
242303 public NtStatus InitializeServerSilo ( NtEvent delete_event , bool downlevel_container , bool throw_on_error )
243304 {
244305 ServerSiloInitInformation init = new ServerSiloInitInformation ( )
@@ -390,6 +451,18 @@ public void SetLimitFlags(JobObjectLimitFlags flags)
390451 SetLimitFlags ( flags , true ) ;
391452 }
392453
454+ /// <summary>
455+ /// Set the Silo system root directory.
456+ /// </summary>
457+ /// <param name="system_root">The absolute path to the system root directory.</param>
458+ /// <param name="throw_on_error">True to throw on error.</param>
459+ /// <remarks>The system_root path must start with a capital drive letter and not end with a backslash.</remarks>
460+ /// <returns>The NT status code.</returns>
461+ public NtStatus SetSiloSystemRoot ( string system_root , bool throw_on_error )
462+ {
463+ return Set ( JobObjectInformationClass . JobObjectSiloSystemRoot , new UnicodeStringIn ( system_root ) , throw_on_error ) ;
464+ }
465+
393466 /// <summary>
394467 /// Set the Silo system root directory.
395468 /// </summary>
0 commit comments