Today, I read this brilliant post from Jawwad Farid and it immediately struck a chord with me.
From my early childhood memories, I remember that things around us were not in such abundance and people generally lived a much simpler life. I remember, we did not have a telephone at home. Having a phone was a privelege. Infact our whole apartment block had just two households with phone. All acquainances just called our neighbours, who would call us attend the call. Try telling it to today's kids in school. They would genuinely struggle with the idea of sharing their cell phones with their siblings. And it wasn't just technical items. All other things like cars, long distance travel, fast food, etc. were scarce and a luxury.
Most the people I know from my childhood have progressed in some form or another. People who came to Karachi from small village and towns in search of better lives have settled down, some have bought property in their ancestral lands. People with motorbikes now have cars - sometimes two. And all of this is from Pakistan, at times when the country have moved from one sort of crisis to another .
So, the question is where has all this money come from? No doubt, technical progress has contributed a lot. Things got cheaper and more accessible. Also, people worked hard and. But, for me one of the greatest reason is the world's definite tilt towards capitalism. In the last two decades, we have seen the world moving from nationalisation and a more state controlled "population focussed" model to a privatised and "profit centric" model. There has been many winners of this model but also the disparity of wealth between wealthy & poor has swelled tremendously. People have more wealth but at the same time they have become more indebted as well.
The current economic meltdown may just prove to be a turning point. We have already seen huge enterprises being bailed out and effectively getting "nationalised", so a lot of things that happened in the last two decardes in being undone. Let's see how far it goes and what the future unfold for all of us.
Tuesday, 31 March 2009
Friday, 20 March 2009
Adding Permissions to a shared folder using WMI and Microsoft .Net
A couple of days ago, I was looking at giving rights to domain users on an already existing shared folder. I searched for it on the net and didn’t find any comprehensive example of how to do it, so thought to put it here to help any desperately lazy developers out there
I am going to assign “Full Control” to a user called “MyDomain\MyUser” on a shared folder called “Shared”. To do this I am using WMI through the .Net System. Management library. WMI is not very intuitive, but once you get hold of it, it’s really powerful to work with all those network objects.
To assign permission to the user, the following needs to be done
The above mentioned steps might seem a lot but once you know which WMI objects to use and how they are related to each other, the actual source code is not difficult.
The following function assigns user to the given shared folder.
The code above is pretty self explanatory, albeit not a good demonstration of catching exceptions and checking for boundary conditions.
As you can see, I am using the ManagementObjectSearcher class to search for shared folder’s setting and user account objects as done in the GetSharedFolderObject() and GetUserAccountObject() methods. Once, we have got the objects, we are working with them to modify and create the related objects necessary to give new permissions.
I am going to assign “Full Control” to a user called “MyDomain\MyUser” on a shared folder called “Shared”. To do this I am using WMI through the .Net System. Management library. WMI is not very intuitive, but once you get hold of it, it’s really powerful to work with all those network objects.
To assign permission to the user, the following needs to be done
- Get hold of the Shared folder object’s setting and extract its security descriptor.
- Extract Access Control List (ACL) from the security descriptor.
- Get hold of the user account object and extract its security descriptor.
- Create a Windows Trustee object for the user using its security descriptor.
- Create an Access Control Entry (ACE) using the Trustee object.
- Add Access Control Entry to Access Control List.
- Assign List back to Security Descriptor for the folder
- Reassign security descriptor to the shared folder.
The above mentioned steps might seem a lot but once you know which WMI objects to use and how they are related to each other, the actual source code is not difficult.
The following function assigns user to the given shared folder.
/// <summary>
/// Creates the share.
/// </summary>
public void AddPermissions(string sharedFolderName, string domain, string userName)
{
// Step 1 - Getting the user Account Object
ManagementObject sharedFolder = GetSharedFolderObject(sharedFolderName);
if (sharedFolder==null)
{
System.Diagnostics.Trace.WriteLine("The shared folder with given name does not exist");
return;
}
ManagementBaseObject securityDescriptorObject = sharedFolder.InvokeMethod("GetSecurityDescriptor", null, null);
if (securityDescriptorObject == null)
{
System.Diagnostics.Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Error extracting security descriptor of the shared path {0}.", sharedFolderName));
return;
}
int returnCode = Convert.ToInt32(securityDescriptorObject.Properties["ReturnValue"].Value);
if (returnCode != 0)
{
System.Diagnostics.Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Error extracting security descriptor of the shared path {0}. Error Code{1}.", sharedFolderName, returnCode.ToString()));
return;
}
ManagementBaseObject securityDescriptor = securityDescriptorObject.Properties["Descriptor"].Value as ManagementBaseObject;
// Step 2 -- Extract Access Control List from the security descriptor
int existingAcessControlEntriesCount = 0;
ManagementBaseObject[] accessControlList = securityDescriptor.Properties["DACL"].Value as ManagementBaseObject[];
if (accessControlList == null)
{
// If there aren't any entries in access control list or the list is empty - create one
accessControlList = new ManagementBaseObject[1];
}
else
{
// Otherwise, resize the list to allow for all new users.
existingAcessControlEntriesCount = accessControlList.Length;
Array.Resize(ref accessControlList, accessControlList.Length + 1);
}
// Step 3 - Getting the user Account Object
ManagementObject userAccountObject = GetUserAccountObject(domain, userName);
ManagementObject securityIdentfierObject = new ManagementObject(string.Format("Win32_SID.SID='{0}'", (string)userAccountObject.Properties["SID"].Value));
securityIdentfierObject.Get();
// Step 4 - Create Trustee Object
ManagementObject trusteeObject = CreateTrustee(domain, userName, securityIdentfierObject);
// Step 5 - Create Access Control Entry
ManagementObject accessControlEntry = CreateAccessControlEntry(trusteeObject, false);
// Step 6 - Add Access Control Entry to the Access Control List
accessControlList[existingAcessControlEntriesCount] = accessControlEntry;
// Step 7 - Assign access Control list to security desciptor
securityDescriptor.Properties["DACL"].Value = accessControlList;
// Step 8 - Assign access Control list to security desciptor
ManagementBaseObject parameterForSetSecurityDescriptor = sharedFolder.GetMethodParameters("SetSecurityDescriptor");
parameterForSetSecurityDescriptor["Descriptor"] = securityDescriptor;
sharedFolder.InvokeMethod("SetSecurityDescriptor", parameterForSetSecurityDescriptor, null);
}
/// <summary>
/// The method returns ManagementObject object for the shared folder with given name
/// </summary>
/// <param name="sharedFolderName">string containing name of shared folder</param>
/// <returns>Object of type ManagementObject for the shared folder.</returns>
private static ManagementObject GetSharedFolderObject(string sharedFolderName)
{
ManagementObject sharedFolderObject = null;
//Creating a searcher object to search
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * from Win32_LogicalShareSecuritySetting where Name = '" + sharedFolderName + "'");
ManagementObjectCollection resultOfSearch = searcher.Get();
if (resultOfSearch.Count > 0)
{
//The search might return a number of objects with same shared name. I assume there is just going to be one
foreach (ManagementObject sharedFolder in resultOfSearch)
{
sharedFolderObject = sharedFolder;
break;
}
}
return sharedFolderObject;
}
/// <summary>
/// The method returns ManagementObject object for the user folder with given name
/// </summary>
/// <param name="domain">string containing domain name of user </param>
/// <param name="alias">string containing the user's network name </param>
/// <returns>Object of type ManagementObject for the user folder.</returns>
private static ManagementObject GetUserAccountObject(string domain, string alias)
{
ManagementObject userAccountObject = null;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(string.Format("select * from Win32_Account where Name = '{0}' and Domain='{1}'", alias, domain));
ManagementObjectCollection resultOfSearch = searcher.Get();
if (resultOfSearch.Count > 0)
{
foreach (ManagementObject userAccount in resultOfSearch)
{
userAccountObject = userAccount;
break;
}
}
return userAccountObject;
}
/// <summary>
/// Returns the Security Identifier Sid of the given user
/// </summary>
/// <param name="userAccountObject">The user object who's Sid needs to be returned</param>
/// <returns></returns>
private static ManagementObject GetAccountSecurityIdentifier(ManagementBaseObject userAccountObject)
{
ManagementObject securityIdentfierObject = new ManagementObject(string.Format("Win32_SID.SID='{0}'", (string)userAccountObject.Properties["SID"].Value));
securityIdentfierObject.Get();
return securityIdentfierObject;
}
/// <summary>
/// Create a trustee object for the given user
/// </summary>
/// <param name="domain">name of domain</param>
/// <param name="userName">the network name of the user</param>
/// <param name="securityIdentifierOfUser">Object containing User's
sid</param>
/// <returns></returns>
private static ManagementObject CreateTrustee(string domain, string userName, ManagementObject securityIdentifierOfUser)
{
ManagementObject trusteeObject = new ManagementClass("Win32_Trustee").CreateInstance();
trusteeObject.Properties["Domain"].Value = domain;
trusteeObject.Properties["Name"].Value = userName;
trusteeObject.Properties["SID"].Value = securityIdentifierOfUser.Properties["BinaryRepresentation"].Value;
trusteeObject.Properties["SidLength"].Value = securityIdentifierOfUser.Properties["SidLength"].Value;
trusteeObject.Properties["SIDString"].Value = securityIdentifierOfUser.Properties["SID"].Value;
return trusteeObject;
}
/// <summary>
/// Create an Access Control Entry object for the given user
/// </summary>
/// <param name="trustee">The user's trustee object</param>
/// <param name="deny">boolean to say if user permissions should be assigned or denied</param>
/// <returns></returns>
private static ManagementObject CreateAccessControlEntry(ManagementObject trustee, bool deny)
{
ManagementObject aceObject = new ManagementClass("Win32_ACE").CreateInstance();
aceObject.Properties["AccessMask"].Value = 0x1U | 0x2U | 0x4U | 0x8U | 0x10U | 0x20U | 0x40U | 0x80U | 0x100U | 0x10000U | 0x20000U | 0x40000U | 0x80000U | 0x100000U; // all permissions
aceObject.Properties["AceFlags"].Value = 0x0U; // no flags
aceObject.Properties["AceType"].Value = deny ? 1U : 0U; // 0 = allow, 1 = deny
aceObject.Properties["Trustee"].Value = trustee;
return aceObject;
}
The code above is pretty self explanatory, albeit not a good demonstration of catching exceptions and checking for boundary conditions.
As you can see, I am using the ManagementObjectSearcher class to search for shared folder’s setting and user account objects as done in the GetSharedFolderObject() and GetUserAccountObject() methods. Once, we have got the objects, we are working with them to modify and create the related objects necessary to give new permissions.
Wednesday, 18 March 2009
Quantitative Easing
The term "Quantitative Easing" has been mentioned quite often in news these days. I didn't know an aweful lot about it and had some time handy today, so thought to study it a bit. I am just jotting down my findings in as simple words as possible.
Wikipedia defines "Quantitative Easing" as a mechanism for central banks to pump liquidity (money supply) in the economy. In other words, central bank will print more money and put it in circulation, so for example if there was £18bn of wealth in circulation through currency notes it would be increased to £20bn of wealth.
So, how do central banks do it?
Well, the honest answers is that it's the central bank and it's standing in the world that determines the wealth for us. A £10 currency note is actually the property of the Bank of England and the idea is that if I give £10 to BoE, it would return me an equivalent amount of "wealth". Now, "wealth" used to be old solid gold in the old days (well, upto 1932). These days its a combination of T-Bills, government bonds and a host of other financial tools. These tools are bought and kept by commercial banks as deposits for the lending they do.
Through quantitative analysis, central banks buy back these bonds and provide cash against these. Since, banks are required to only keep a percentage of their deposits as reserve (say 50%), increasing liquidity in banks by say £1000 would enable them to lend out £2000. This increase the money supply to banks, who can then lend them to individuals and business.
Negative Effects:
With more money in circulation, there will be more money chasing lesser goods making everything more "expensive". There is a genuine risks of inflation shooting through the roof. It depreciates the "actual" value of assetts for investers and devalues the currency.
Who's doing it?
Bank of England announced it earlier this month. And today, the Federal Reserve in US has announced it. The scale of money pumping in by the US is mind boggling. Of course, both the economies are hit hard by the credit crunch and are undergoing negative inflation.
Winners & Loosers:
The winners would be banks and financial companies. With the value of money reducing, the actual value of their bad debts would go down and they would have more cash to lend. After Quantitative Easing, a bad debt of say £100,000 would have the same effect as a bad debt of £90,000.
The biggest loosers, I think, would be Asian and OPEC countries, who keep their reserves in dollars. All gulf countries, for example, have pegged their currencies against dollars. A devaluation of dollars would devalue their currencies and reduce their wealth. Also, countries like China and India have hoarded huge sums of dollars. They will see the actual value of their dollar based wealth dwindle.
What next?
I am quite keen to see
1) How China respond to this announcement by Federal Reserve today? Will they be selling T-Bills? Would it switch buy more Euro based assetts?
2) Will the European Central Bank adopt Quantitative Easing? This is one of the sternest test of the European Economic Commission. They have countries like Germany & France on one end, which would want it to happen and have countries like Poland, which still have strong inflationary pressure and would not want to do it.
Wikipedia defines "Quantitative Easing" as a mechanism for central banks to pump liquidity (money supply) in the economy. In other words, central bank will print more money and put it in circulation, so for example if there was £18bn of wealth in circulation through currency notes it would be increased to £20bn of wealth.
So, how do central banks do it?
Well, the honest answers is that it's the central bank and it's standing in the world that determines the wealth for us. A £10 currency note is actually the property of the Bank of England and the idea is that if I give £10 to BoE, it would return me an equivalent amount of "wealth". Now, "wealth" used to be old solid gold in the old days (well, upto 1932). These days its a combination of T-Bills, government bonds and a host of other financial tools. These tools are bought and kept by commercial banks as deposits for the lending they do.
Through quantitative analysis, central banks buy back these bonds and provide cash against these. Since, banks are required to only keep a percentage of their deposits as reserve (say 50%), increasing liquidity in banks by say £1000 would enable them to lend out £2000. This increase the money supply to banks, who can then lend them to individuals and business.
Negative Effects:
With more money in circulation, there will be more money chasing lesser goods making everything more "expensive". There is a genuine risks of inflation shooting through the roof. It depreciates the "actual" value of assetts for investers and devalues the currency.
Who's doing it?
Bank of England announced it earlier this month. And today, the Federal Reserve in US has announced it. The scale of money pumping in by the US is mind boggling. Of course, both the economies are hit hard by the credit crunch and are undergoing negative inflation.
Winners & Loosers:
The winners would be banks and financial companies. With the value of money reducing, the actual value of their bad debts would go down and they would have more cash to lend. After Quantitative Easing, a bad debt of say £100,000 would have the same effect as a bad debt of £90,000.
The biggest loosers, I think, would be Asian and OPEC countries, who keep their reserves in dollars. All gulf countries, for example, have pegged their currencies against dollars. A devaluation of dollars would devalue their currencies and reduce their wealth. Also, countries like China and India have hoarded huge sums of dollars. They will see the actual value of their dollar based wealth dwindle.
What next?
I am quite keen to see
1) How China respond to this announcement by Federal Reserve today? Will they be selling T-Bills? Would it switch buy more Euro based assetts?
2) Will the European Central Bank adopt Quantitative Easing? This is one of the sternest test of the European Economic Commission. They have countries like Germany & France on one end, which would want it to happen and have countries like Poland, which still have strong inflationary pressure and would not want to do it.
Friday, 13 March 2009
New release of Microsoft StyleCop
A new version of Microsoft StyleCop was released yesterday. If you are not already using StyleCop, do it try it out. For years, I have been frustrated by developers using inconsistent layouts, variables defined all over the place, different styles, etc which effect the readability of the code. This is where stylecop comes handy and once integrated into the build process, it would flag all inconsistencies in the project. This ensures that code is readable and maintainable throughout.
If you are using MSBuild Entension Pack, there is a task defined for running StyleCop. Integrate it into your CI build and the developers would instantly know if a developer have done some misdemeanour :)
If you are using MSBuild Entension Pack, there is a task defined for running StyleCop. Integrate it into your CI build and the developers would instantly know if a developer have done some misdemeanour :)
Friday, 6 March 2009
Say yes to "No"
Josh Billings once famously said
"One-half the troubles of this life can be traced to saying yes too quickly..."
and reflecting back, this is certainly something true to my life. I have often found myself worried about doing things, which I could have avoided. I think, my habbit is rooted from my cultural background.
The fact it that people from Indian subcontinent are not used to hearing apologies. So, if someone invites you for dinner, for instance, and you can't make it, it can become really difficult to excuse out of it. People would insist and insist until you agree to what they are asking. The result is that people end up making commitments that they can't meet and people saying things they don't really mean. I, for one, find it frustrating.
"One-half the troubles of this life can be traced to saying yes too quickly..."
and reflecting back, this is certainly something true to my life. I have often found myself worried about doing things, which I could have avoided. I think, my habbit is rooted from my cultural background.
The fact it that people from Indian subcontinent are not used to hearing apologies. So, if someone invites you for dinner, for instance, and you can't make it, it can become really difficult to excuse out of it. People would insist and insist until you agree to what they are asking. The result is that people end up making commitments that they can't meet and people saying things they don't really mean. I, for one, find it frustrating.
Tuesday, 3 March 2009
ASP.net MVC Framwork Part 3
In my previous post, I wrote about the Microsoft ASP.Net MVC Framework and demonstrated with the help of a simple application, how it simplifies the use Model-View-Controller design pattern in web applications. The ultimate motive for using the patter is of course to achieve seperation of business and presentation logic.
In this post, I will write about what actually happens under the hood in the MVC framework and how does it enables us to create more simpler applications. The underlying technology used in the MVC framework is not new. If you are familiar with the Micorosoft Internet Information server (IIS), you would have surely heard about ISAPI Extensions and ISAPI Filters.
ISAPI Extensions are program that run on the IIS web server and have access to the functionality provided by IIS. They are the ultimate target of all web requests and are responsible for processing them. ISAP Filters are programs through which all client requests are filtered through before they are finally processed by ISAPI extensions.
To harness the functionality of ISAPI Exentions and ISAPI filter, ASP.Net provides Http Handlers and Http Modules respectively. A following pictures gives a graphical representation of a web request through HTTP Modules and HTTP Handlers.
The HTTP Handler class must implement the IHTTPHandler interface in the System.Web namespace. For every type of web request, an HTTP handler must exist to preocess it. In a web application, the Http Handlers to process different kinds of files are listed in the web.config file. The following code snippet shows an example of all HTTP
As you might have guessed so far, the functionality of MVC framework is provided through HTTP Module and HTTP Handlers, which provides all the functionailty of routing and passing data between controller and view.
To process the custom URL, the framework make use of UrlRoutingModule. In the above extract from web.config, you will find the the entry
<add name="urlRouting" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing"/>
A RouteTable needs to be defined to handle the URL pattern. This is done in the Application_OnStart event in the global.asax file. This is shown below:
Inside the method RegisterRoute, there is a call routes.MapRoute, which takes three parameter. The first parameter is the name of the route, the second parameter contains the pattern of URL and the three parameter contains default values for URL.
As you can see, the pattern used in URL is "{Controller}/{Action}/{Id}". When the URL is called, the class in the controller section is called as controller, the action value is set through the action part of URL and if there is a record selected then the Id is passed through the Id section.
The HTTP module System.Web.Routing.UrlRoutingModule makes sure that requests are passed to controller and that all data submitted from the view is passed to it.
In this post, I will write about what actually happens under the hood in the MVC framework and how does it enables us to create more simpler applications. The underlying technology used in the MVC framework is not new. If you are familiar with the Micorosoft Internet Information server (IIS), you would have surely heard about ISAPI Extensions and ISAPI Filters.
ISAPI Extensions are program that run on the IIS web server and have access to the functionality provided by IIS. They are the ultimate target of all web requests and are responsible for processing them. ISAP Filters are programs through which all client requests are filtered through before they are finally processed by ISAPI extensions.
To harness the functionality of ISAPI Exentions and ISAPI filter, ASP.Net provides Http Handlers and Http Modules respectively. A following pictures gives a graphical representation of a web request through HTTP Modules and HTTP Handlers.
The HTTP Handler class must implement the IHTTPHandler interface in the System.Web namespace. For every type of web request, an HTTP handler must exist to preocess it. In a web application, the Http Handlers to process different kinds of files are listed in the web.config file. The following code snippet shows an example of all HTTP
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ScriptModule"/>
<remove name="UrlRoutingModule"/>
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>
<handlers>
<remove name="ScriptHandlerFactory"/>
<remove name="ScriptHandlerFactoryAppServices"/>
<remove name="ScriptResource"/>
<remove name="MvcHttpHandler"/>
<remove name="UrlRoutingHandler"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</handlers>
</system.webServer>
As you might have guessed so far, the functionality of MVC framework is provided through HTTP Module and HTTP Handlers, which provides all the functionailty of routing and passing data between controller and view.
To process the custom URL, the framework make use of UrlRoutingModule. In the above extract from web.config, you will find the the entry
<add name="urlRouting" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing"/>
A RouteTable needs to be defined to handle the URL pattern. This is done in the Application_OnStart event in the global.asax file. This is shown below:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
Inside the method RegisterRoute, there is a call routes.MapRoute, which takes three parameter. The first parameter is the name of the route, the second parameter contains the pattern of URL and the three parameter contains default values for URL.
As you can see, the pattern used in URL is "{Controller}/{Action}/{Id}". When the URL is called, the class in the controller section is called as controller, the action value is set through the action part of URL and if there is a record selected then the Id is passed through the Id section.
The HTTP module System.Web.Routing.UrlRoutingModule makes sure that requests are passed to controller and that all data submitted from the view is passed to it.
Subscribe to:
Posts (Atom)