Jump to content

Recommended Posts

Posted

Hi,

Could I ask whether somebody been able set successfully the FSRM Quota which are using the folders, not whole volumes. If yes - how the the expressions shouldbe set up?

I searched through forum but only found this thread "[HAP+][v8] - File Server Resource Management Quota Testers" which been not updated since February. For now I'm not quite sure whether this feature should really are working or is still in deployment stage.

 

I tried set up using several different combinations of expressions but always home drive are showing just full green bar with no information about drive space. It should everything OK with my configuration as I can get quota information from other server what are not using FSRM.

I test it on version 7.10 using quota service which could be downloaded from codeplex website and “HAP+Web 7.10 Alpha” which I found in thread which I mentioned earlier.

 

Thanks in advance.

Mario

Posted
Since I don't use FSRM I can't test or make something that works properly. If someone is willing to write a new FSRM Quota Service I'll happily use it.
Posted

Hi Nick,

 

Have had a quick look at this issue and have had a quick look at the code.

 

I think I've found a small booboo in the code which would cause this problem.

 

In the file ComputerBrowser Quota.CS, the function HAP.Data.Quota.QuotaInfo decides whether to call the original drive quota function or the FSRM quota function depending on whether the username string is null.

 

if (string.IsNullOrEmpty(username)) c.GetQuotaFromPath(share);

return c.GetQuota(username, server.Drive.ToString() + ":");

 

Because the return clause always executes the original function, it looks like the QuotaInfo structure returned from the FSRM version is always overwritten with the original version (Looks like your function QuotaInfo GetQuota(...) always returns a new QuotaInfo structure, even if drive quotas are not operational).

 

Could I suggest something along the lines of:

 

if (string.IsNullOrEmpty(username)) return c.GetQuotaFromPath(share)

else return c.GetQuota(username, server.Drive.ToString() + ":");

 

Is this any help? Sorry I've mis-read the code.

 

Thanks for HAP+

 

Moby.

 

Since I don't use FSRM I can't test or make something that works properly. If someone is willing to write a new FSRM Quota Service I'll happily use it.
Posted

Hi Nick,

 

I've tried downloading the latest HAP+ snapshot into VC2010, but can't as yet get it to compile :(

 

Is there any chance you could make the change to the return statement (so that the original GetQuota function is either not always called or does not overwrite the "c" QuotaInfo structure from the call to GetQuotaFromPath invocation) and let us have a copy of the modified file to test? I'd be very grateful!

 

Thanks in advance!

Moby

Posted

Hi Nick,

 

Still doesn't work, sorry.

 

I don't know what change you made, but can I make one more suggestion?

 

The previous logic

if (string.IsNullOrEmpty(username)) c.GetQuotaFromPath(share);

return c.GetQuota(username, server.Drive.ToString() + ":");

assumes that the username string will not be used when FSRM quotas are used. Hope I've not got this wrong, sorry if I have, but why would this field be empty when using FSRM quotas?

 

The typical path to check for quotas will be \\servername\sharename\%username% so the username field would still be important here to build the correct path to check for FSRM quotas.

 

Instead of a %username% for the quota server, if I put in the quota path fixed (e.g. \\server\sharename\bob - so it would only work for one user called "bob") then the green bar shows.

 

Unfortunately the green bar shows a wrong value (e.g. -81613.72%)... Not sure why this.. if I can, I try to build a small sample EXE that uses your GetQuotaFromPath function and verify operation, if that helps.

 

Could you check the need for the username string? I think it's still needed & is not a valid test as to which quota function is called. Maybe call the FSRM one, and then if no quota returned, call the original drive quota function? Hope this all makes sense, thanks for your help with this again...

 

Moby.

Posted

Hi Nick,

 

Done some more thinking and lookinh on this :)

 

Could you make one or two more changes please and see how we go?

 

Your original quota function used the drive volume letter to get the quota. Your new function uses the share, but I don't (think) the FSRM API allow UNC paths. We therefore need to convert the UNC path back to a local path, so that the correct directory can be evaluated for quota (and %username% can also then be used). Something along the lines of (untested):

 

Uri uri = new Uri(share)

return c.GetQuotaFromPath(server.Drive.ToString() + ":" + Uri.AbsolutePath);

 

Of course, this approach would only work where the parent folder of the home drive was off the root of the disk volume (e.g. where \\servername\sharename, Drive E in settings, was E:\sharename, not e:\myshares\sharename). Given that most home folders in most schools are shared off at least one-subdir, it's not an effective workaround.

 

The best solution (but more work for you) would be to fully resolve UNC paths to local paths, below. (borrowed a chunk from Programming FSRM quotas | How Things (Should) Work)

 

I'd be very grateful if you could have another stab at this and I'd be glad to test anything you come up with. :)

 

Lastly, the %username% field might be specified for FSRM quota home drives as any other, so %username% is not a good test as to whether to call the original or new FSRM function - maybe call the FSRM one, and then if no quota or NIL is returned, call the original function.

 

Thanks,

Moby.

 

return c.GetQuotaFromPath(GetPath(share));

 

 

using System.Management;

 

public static string GetPath(string uncPath)

{

try

{

// remove the "\\" from the UNC path and split the path

uncPath = uncPath.Replace(@"\\", "");

string[] uncParts = uncPath.Split(new char[] {'\\'}, StringSplitOptions.RemoveEmptyEntries);

if (uncParts.Length < 2)

return "[uNRESOLVED UNC PATH: " + uncPath + "]";

// Get a connection to the server as found in the UNC path

ManagementScope scope = new ManagementScope(@"\\" + uncParts[0] + @"\root\cimv2");

// Query the server for the share name

SelectQuery query = new SelectQuery("Select * From Win32_Share Where Name = '" + uncParts[1] + "'");

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

 

// Get the path

string path = string.Empty;

foreach (ManagementObject obj in searcher.Get())

{

path = obj["path"].ToString();

}

 

// Append any additional folders to the local path name

if (uncParts.Length > 2)

{

for (int i = 2; i < uncParts.Length; i++)

path = path.EndsWith(@"\") ? path + uncParts : path + @"\" + uncParts;

}

 

return path;

}

catch (Exception ex)

{

return "[ERROR RESOLVING UNC PATH: " + uncPath + ": "+ex.Message+"]";

}

}

Posted

I've changed the Quota Service so it does the lookup you've posted as well.

 

       public QuotaInfo GetQuotaFromPath(string path)
       {
           IFsrmQuotaManager FSRMQuotaManager = new FsrmQuotaManagerClass();
           IFsrmQuota Quota = null;
           try
           {
               Quota = FSRMQuotaManager.GetQuota(path);
               QuotaInfo q = new QuotaInfo();
               q.Free = (int)Quota.QuotaLimit - (int)Quota.QuotaUsed;
               q.Used = (int)Quota.QuotaUsed;
               q.Total = (int)Quota.QuotaLimit;
               return q;
           }
           catch
           {
               try
               {
                   Quota = FSRMQuotaManager.GetQuota(GetPath(path));
                   QuotaInfo q = new QuotaInfo();
                   q.Free = (int)Quota.QuotaLimit - (int)Quota.QuotaUsed;
                   q.Used = (int)Quota.QuotaUsed;
                   q.Total = (int)Quota.QuotaLimit;
                   return q;
               }
               catch
               {
               }
               return new QuotaInfo();
           }
       }

 

You can use the WCFTestClient to test the service to see if it does what you need: WCF Test Client (WcfTestClient.exe)

 

This is the code for the GetQuota function in the core of HAP.Data, note that this is fired by the API call from the website. This function looks up which server to send the request for quota information to

 

       public static HAP.Data.Quota.QuotaInfo GetQuota(string username, string share)
       {
           QuotaServer server = null;
           foreach (QuotaServer s in hapConfig.Current.MySchoolComputerBrowser.QuotaServers)
               if (share.ToLower().StartsWith(s.Expression.Replace("%username%", username).ToLower()))
                   server = s;
           if (server == null) throw new Exception("Can't find quota server");
           string endPointAddr = "net.tcp://" + server.Server + ":8010/HAPQuotaService";
           NetTcpBinding tcpBinding = new NetTcpBinding();
           tcpBinding.TransactionFlow = false;
           tcpBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
           tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
           tcpBinding.Security.Mode = SecurityMode.None; 
           EndpointAddress endpointAddress = new EndpointAddress(endPointAddr);
           ServiceClient c = new ServiceClient(tcpBinding, endpointAddress);
           if (server.FSRM) return c.GetQuotaFromPath(share);
           return c.GetQuota(username, server.Drive.ToString() + ":");
       }

Posted

Hi Nick,

 

Thanks for this, I'll test as soon as I can. Can I just ask - how is the server.FSRM property set? Where will this get set "true" is FSRM is in use, i.e. does the user have to configure something somewhere?

 

Ta

Moby

Posted

OK... Do you want me to test just the service operation using the WCF util, or to try a V8 alpha build, if these are available for download?

 

Thanks again Nick, you're a star !

 

Moby

Posted

Hi Nick,

 

Got around to testing this as soon as possible, just now.

 

The zip link you sent won't install - during install it says error 1001 Exception occurred while initialiazing the installation: System.BadImageFormatException.

 

Do I need an x64 version, or can you do me another build & I'll try to test asap...

 

Many thanks,

Moby

Posted

Tried also the versions on your Skydrive (from your alpha posting) - the version labelled x86 does not install (same problem) but the larger version does install. Obviously however I don't know if this is a build containing the functions you wanted testing :)

 

However, when I try to bind to the endpoint with

 

net.tcp://192.168.1.26:8010/HAPQuotaService

 

it tells me that it cannot obtain the service metadata.

 

Regards

Moby

Posted

x86 is for Windows Server 2003 or where the Drive Quota System is used. The x64 should be the one to use on most new servers.

 

The Service Meta Data is on port 8011

Posted (edited)

The file "HAP Quota Service Setup x86" from your skydrive is the only one that installs. Does this contain the test code?

 

When I test with http://192.168.1.26:8011/HAPQuotaService using the test client, the function GetQuotaFromPath always returns -1 (for Free, Total and Used), with the path specified as e:\home\teststudent, or \\srv01\home\teststudent (or any other path).

 

(BTW, if I enable the old disk quotas, the function GetQuota returns Total & Used (but Free as -1)).

 

Thanks

Moby

Edited by mobybrick
Posted (edited)

Hi Nick,

 

I built a standalone EXE to test operation of the FSRM quota code and verified correct operation.

 

If a UNC is entered in the string below in the following console application, the console works correctly. So as long as a full UNC is passed to GetQuota then everything should be fine. This makes me think that so far the WCFClientTest I have done is against a wrong build of the quota server. Could you rebuild this for me for x64 for another test?

 

Hope this helps,

Moby.

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using DiskQuotaTypeLibrary;

using Microsoft.Storage;

using System.Runtime.InteropServices;

using System.IO;

using System.Management;

 

namespace FSFRMAPITest1

{

class Program

{

static void Main(string[] args)

{

string path="\\\\srv01\\home\\teststudent";

Console.WriteLine("{0}", path);

IFsrmQuotaManager FSRMQuotaManager = new FsrmQuotaManager();

IFsrmQuota Quota = null;

long qFree = 0;

long qTotal = 0;

long qUsed = 0;

try

{

Quota = FSRMQuotaManager.GetQuota(path);

 

qFree = (int)Quota.QuotaLimit - (int)Quota.QuotaUsed;

qUsed = (int)Quota.QuotaUsed;

qTotal = (int)Quota.QuotaLimit;

Console.WriteLine("1: {0} {1} {2}",qFree,qUsed,qTotal);

}

catch

{

try

{

Quota = FSRMQuotaManager.GetQuota(GetPath(path));

 

qFree = (int)Quota.QuotaLimit - (int)Quota.QuotaUsed;

qUsed = (int)Quota.QuotaUsed;

qTotal = (int)Quota.QuotaLimit;

Console.WriteLine("2: {0} {1} {2}", qFree, qUsed, qTotal);

}

catch

{

Console.WriteLine("3: Failed");

}

Console.WriteLine("This would return NULL");

}

 

}

 

public static string GetPath(string uncPath)

{

try

{

// remove the "\\" from the UNC path and split the path

uncPath = uncPath.Replace(@"\\", "");

string[] uncParts = uncPath.Split(new char[] {'\\'}, StringSplitOptions.RemoveEmptyEntries);

if (uncParts.Length < 2)

return "[uNRESOLVED UNC PATH: " + uncPath + "]";

// Get a connection to the server as found in the UNC path

ManagementScope scope = new ManagementScope(@"\\" + uncParts[0] + @"\root\cimv2");

// Query the server for the share name

SelectQuery query = new SelectQuery("Select * From Win32_Share Where Name = '" + uncParts[1] + "'");

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

Console.WriteLine("Here tom");

// Get the path

string path = string.Empty;

foreach (ManagementObject obj in searcher.Get())

{

path = obj["path"].ToString();

}

 

// Append any additional folders to the local path name

if (uncParts.Length > 2)

{

for (int i = 2; i < uncParts.Length; i++)

path = path.EndsWith(@"\") ? path + uncParts : path + @"\" + uncParts;

}

 

return path;

}

catch (Exception ex)

{

return "[ERROR RESOLVING UNC PATH: " + uncPath + ": "+ex.Message+"]";

}

}

}

}

Edited by mobybrick
Posted
Hmm, I can't see anything wrong with the installer, I've rebuilt it, and readded the references. HAP.Data.Quota should be 32bit, but the actual service should be 64bit.
Posted

There's something up with the installer I'm afraid. Even trying to install on a fresh new machine fails. Because the installer fails (and deletes any files it tried to copy) with the bad image format error, I can't test anything :(

 

Event viewer shows:

 

The description for Event ID 11001 from source MsiInstaller cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

 

If the event originated on another computer, the display information had to be saved with the event.

 

The following information was included with the event:

 

Product: HAP Quota Service x86 -- Error 1001. Error 1001. Exception occurred while initializing the installation:

System.BadImageFormatException: Could not load file or assembly 'file:///C:\Program Files\nb development\HAP Quota Service x86\HAP Quota Service.exe' or one of its dependencies. An attempt was made to load a program with an incorrect format..

(NULL)

(NULL)

(NULL)

(NULL)

(NULL)

 

the message resource is present but the message is not found in the string/message table

 

 

Do you need x64 versions of the dependancy dlls, or has there been any other change?

 

M

Posted

Try this again, I've removed the custom action that was being used to register the service. You will need to browse to %programfiles%\nb development\HAP Quota Service and run Register.vbs.

 

You will need to run Remove.vbs before you uninstall. I'm looking into why this is happening

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...