Programming FSRM quotas

Introduction

Recently I was evaluating the options I had for implementing disk quotas on a backend system running on a major Internet Service Provider in Brazil.

Windows offers quota management up to some degree since NTFS 5 (Windows 2000) with user/volume quotas. Those were not appropriate for our scenario since we needed to set quotas on a per directory basis and this was not supported natively by Windows until the arrival of Windows Server 2003 R2.

R2 brings us a new feature called File Server Resource Manager a.k.a. FSRM. It is exposed for the system administrator as an MMC 3.0 snap-in.

Unfortunately, as of today Microsoft does not officially support any way for programming against FSRM quotas.  I said “officially support” because if the snap-in can do it, probably we can too! So after some research I found two DLLs called srm.dll and srmlib.dll that happens to do the stuff we want. Srm.dll exposes FSRM functionality through COM and srmlib.dll is a managed code wrapper around srm.dll.

Let’s take a look at some sample code:

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.Storage;

using System.IO;

using System.Runtime.InteropServices;

 

namespace Fsrm {

    class Program {

        static void Main(string[] args) {

            string directoryName = @"c:FsrmTests";

 

            // Creates a directory for testing if necessary

            if (!Directory.Exists(directoryName)) {

                Directory.CreateDirectory(directoryName);

            }

           

            ISrmQuotaManager quotaManager = new SrmQuotaManagerClass();

            ISrmQuota quota = null;

            try {

                // Try to get quota info

                quota = quotaManager.GetQuota(directoryName);

                quota.QuotaLimit *= 2;

            }

            catch (COMException ex) {

                unchecked {

                    if (ex.ErrorCode == (int)0x80045301) {

                        // Quota doesn’t exist for this directory. Create it.

                        Console.WriteLine("No quota defined for ‘{0}’. Creating quota.", directoryName);

                        quota = quotaManager.CreateQuota(directoryName);

                        quota.QuotaLimit = 1024 * 1024;

                    }

                    else {

                        Console.WriteLine(ex);

                        return;

                    }

                }

            }

 

            // Update quota info

            quota.Commit();

 

            // Add new file to the diretory to see QuotaUsed getting updated

            File.WriteAllText(directoryName + @"" + Path.GetRandomFileName() + ".txt", "Testing FSRM directory quotas");

            Console.WriteLine("New file added. Quota doubledrn{0} of {1} used.", quota.QuotaUsed, quota.QuotaLimit);

        }

    }

}

 

This sample doubles the size of the directory’s quota and puts a file in it every time it is run.

There are a bunch of other classes and methods available. Have fun!