Don’t you hate when you have access denied and you don’t know where it is coming from? It is even worse when it is related to anonymous access where a single detail can prevent a page from being rendered (IIS authentication, broken inheritance, you name it). The application will show the detailed cascade rights for anonymous, current user and given user for a given item in url. In the example below it will show all details from site to page item:

 

image

image

The output will look like it:

 

Object Type: File
**** Start Miscellaneous for Site
http://rviana-moss-w28
IIS Allow Anonymous:  [True]
IIS is impersonating: [False]
Zone:                 [Default]
Host Name:            [rviana-moss-w28]
Write Locked:         [False]
**** End Miscellaneous for Site
**** Start Miscellaneous for Web
http://rviana-moss-w28
Web Allow Anonymous:  [True]
Anonymous Access to Lists and Libraries:  [On]
********* Start of List of Rights to anonymous in this web
Perm Mask  -  Hex: 1000031041 Binary 1000000000000000000110001000001000001
    ViewListItems Hex [00000001] Binary [1]
    ViewVersions Hex [00000040] Binary [1000000]
    ViewFormPages Hex [00001000] Binary [1000000000000]
    Open Hex [00010000] Binary [10000000000000000]
    ViewPages Hex [00020000] Binary [100000000000000000]
    UseClientIntegration Hex [1000000000] Binary [1000000000000000000000000000000000000]
    FullMask Hex [1000031041] Binary [1000000000000000000110001000001000001]
********* End of List of Rights to anonymous in this web

********* Start of List of Rights for User CONTOSO\alanew
Perm Mask  -  Hex: 1b03c4312ef Binary 11011000000111100010000110001001011101111
    ViewListItems Hex [00000001] Binary [1]
    AddListItems Hex [00000002] Binary [10]
    EditListItems Hex [00000004] Binary [100]
    DeleteListItems Hex [00000008] Binary [1000]
    OpenItems Hex [00000020] Binary [100000]
    (... lines removed for space ...)
    CreateAlerts Hex [8000000000] Binary [1000000000000000000000000000000000000000]
    EditMyUserInfo Hex [10000000000] Binary [10000000000000000000000000000000000000000]
    FullMask Hex [1b03c4312ef] Binary [11011000000111100010000110001001011101111]
********* End of List of Rights

********* Start of List of Rights for Current User CONTOSO\rviana
Perm Mask  -  Hex: 7fffffffffffffff Binary 111111111111111111111111111111111111111111111111111111111111111
    ViewListItems Hex [00000001] Binary [1]
    AddListItems Hex [00000002] Binary [10]
    EditListItems Hex [00000004] Binary [100]
    DeleteListItems Hex [00000008] Binary [1000]
    (... lines removed for space ...)
    EditMyUserInfo Hex [10000000000] Binary [10000000000000000000000000000000000000000]
    EnumeratePermissions Hex [4000000000000000] Binary [100000000000000000000000000000000000000000000000000000000000000]
    FullMask Hex [7fffffffffffffff] Binary [111111111111111111111111111111111111111111111111111111111111111]
********* End of List of Rights

**** End Miscellaneous for Web

**** Start Miscellaneous for List Pages at /Pages/Forms/AllItems.aspx
Access to Template List is Restricted     :  [False]
Users Access Limited to Items they Created:  [False]
Anonymous can access                      :  [True]
Everyone can view List                    :  [False]
********* Start of List of Rights to anonymous in this List
Perm Mask  -  Hex: 1000031041 Binary 1000000000000000000110001000001000001
    ViewListItems Hex [00000001] Binary [1]
    ViewVersions Hex [00000040] Binary [1000000]
    ViewFormPages Hex [00001000] Binary [1000000000000]
    Open Hex [00010000] Binary [10000000000000000]
    ViewPages Hex [00020000] Binary [100000000000000000]
    UseClientIntegration Hex [1000000000] Binary [1000000000000000000000000000000000000]
    FullMask Hex [1000031041] Binary [1000000000000000000110001000001000001]
********* End of List of Rights to anonymous in this List

********* Start of List of Rights for User CONTOSO\alanew
Perm Mask  -  Hex: 1b03c4312ef Binary 11011000000111100010000110001001011101111
    ViewListItems Hex [00000001] Binary [1]
    AddListItems Hex [00000002] Binary [10]
    EditListItems Hex [00000004] Binary [100]
    DeleteListItems Hex [00000008] Binary [1000]
    OpenItems Hex [00000020] Binary [100000]
    ViewVersions Hex [00000040] Binary [1000000]
    (... lines removed for space ...)
    EditMyUserInfo Hex [10000000000] Binary [10000000000000000000000000000000000000000]
    FullMask Hex [1b03c4312ef] Binary [11011000000111100010000110001001011101111]
********* End of List of Rights

********* Start of List of Rights for Current User CONTOSO\rviana
Perm Mask  -  Hex: 7fffffffffffffff Binary 111111111111111111111111111111111111111111111111111111111111111
    ViewListItems Hex [00000001] Binary [1]
    AddListItems Hex [00000002] Binary [10]
    (... lines removed for space ...)
    EditMyUserInfo Hex [10000000000] Binary [10000000000000000000000000000000000000000]
    EnumeratePermissions Hex [4000000000000000] Binary [100000000000000000000000000000000000000000000000000000000000000]
    FullMask Hex [7fffffffffffffff] Binary [111111111111111111111111111111111111111111111111111111111111111]
********* End of List of Rights

**** End Miscellaneous for List

**** Start Miscelaneous for List Item default.aspx at Pages/default.aspx
Anonymous has access to list item    :  [True]
Permission Inheritance is broken     :  [False]
********* Start of List of Rights for User CONTOSO\alanew
Perm Mask  -  Hex: 1b03c4312ef Binary 11011000000111100010000110001001011101111
    ViewListItems Hex [00000001] Binary [1]
    AddListItems Hex [00000002] Binary [10]
    EditListItems Hex [00000004] Binary [100]
    (... lines removed for space ...)
    UpdatePersonalWebParts Hex [20000000] Binary [100000000000000000000000000000]
    UseClientIntegration Hex [1000000000] Binary [1000000000000000000000000000000000000]
    UseRemoteAPIs Hex [2000000000] Binary [10000000000000000000000000000000000000]
    CreateAlerts Hex [8000000000] Binary [1000000000000000000000000000000000000000]
    EditMyUserInfo Hex [10000000000] Binary [10000000000000000000000000000000000000000]
    FullMask Hex [1b03c4312ef] Binary [11011000000111100010000110001001011101111]
********* End of List of Rights

********* Start of List of Rights for Current User CONTOSO\rviana
Perm Mask  -  Hex: 7fffffffffffffff Binary 111111111111111111111111111111111111111111111111111111111111111
    ViewListItems Hex [00000001] Binary [1]
    AddListItems Hex [00000002] Binary [10]
    EditListItems Hex [00000004] Binary [100]
    (... lines removed for space ...)
    EnumeratePermissions Hex [4000000000000000] Binary [100000000000000000000000000000000000000000000000000000000000000]
    FullMask Hex [7fffffffffffffff] Binary [111111111111111111111111111111111111111111111111111111111111111]
********* End of List of Rights

********* Item Xml
<z:row xmlns:z='#RowsetSchema' ows_ContentTypeId='0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D400B86BB823B4EF734998C6CF97A89029EE' ows_FileLeafRef='1;#default.aspx' ows_Modified_x0020_By='SHAREPOINT\system' ows_File_x0020_Type='aspx' ows_Title='Search Center' ows_PublishingPageLayout='
http://rviana-moss-w28/_catalogs/masterpage/searchmain.aspx, Search Page' ows_ContentType='Welcome Page' ows_ID='1' ows_Created='2010-10-22 20:43:50' ows_Author='1073741823;#System Account' ows_Modified='2010-10-22 20:43:50' ows_Editor='1073741823;#System Account' ows__ModerationStatus='0' ows_FileRef='1;#Pages/default.aspx' ows_FileDirRef='1;#Pages' ows_Last_x0020_Modified='1;#2010-10-22 20:43:50' ows_Created_x0020_Date='1;#2010-10-22 20:43:50' ows_File_x0020_Size='1;#739' ows_FSObjType='1;#0' ows_PermMask='0x7fffffffffffffff' ows_CheckedOutUserId='1;#' ows_IsCheckedoutToLocal='1;#0' ows_UniqueId='1;#{B9F29A82-3E82-4817-B8A5-77CED27512E8}' ows_ProgId='1;#' ows_ScopeId='1;#{037929C6-B73A-4F2B-BD14-07003EADB4CD}' ows_VirusStatus='1;#739' ows_CheckedOutTitle='1;#' ows__CheckinComment='1;#' ows__EditMenuTableStart='default.aspx' ows__EditMenuTableEnd='1' ows_LinkFilenameNoMenu='default.aspx' ows_LinkFilename='default.aspx' ows_DocIcon='aspx' ows_ServerUrl='/Pages/default.aspx' ows_EncodedAbsUrl='http://rviana-moss-w28/Pages/default.aspx' ows_BaseName='default' ows_FileSizeDisplay='739' ows_MetaInfo='1;#vti_modifiedby:SR|SHAREPOINT\\system
vti_parserversion:SR|12.0.0.6545
vti_cachedhastheme:BR|false
vti_cachedcustomprops:VX|ContentType vti_title PublishingPageLayout
ContentType:SW|Welcome Page
vti_title:SR|Search Center
vti_cachedtitle:SR|Search Center
vti_charset:SR|utf-8
ContentTypeId:SW|0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D400B86BB823B4EF734998C6CF97A89029EE
PublishingPageLayout:SW|/_catalogs/masterpage/searchmain.aspx, Search Page
vti_author:SR|
vti_setuppath:SX|SiteTemplates\\SRCHCEN\\default.aspx
vti_cachedneedsrewrite:BR|false
' ows__Level='1' ows__IsCurrentVersion='1' ows_SelectTitle='1' ows_SelectFilename='1' ows_Edit='0' ows_owshiddenversion='2' ows__UIVersion='512' ows__UIVersionString='1.0' ows_Order='100.000000000000' ows_GUID='{5FAA46F1-443E-4FF7-A60B-7A229EBD9C03}' ows_WorkflowVersion='1' ows_ParentVersionString='1;#' ows_ParentLeafName='1;#' ows_Combine='0' ows_RepairDocument='0' ows_ServerRedirected='0'/>


********* End of Item XML

********* Role Assignments Xml
<permissions><permission memberid='3' mask='9223372036854775807' />
<permission memberid='4' mask='756052856929' />
<permission memberid='5' mask='1856436900591' />
<permission memberid='6' mask='206292717568' />
<permission memberid='7' mask='1856438737919' />
<permission memberid='8' mask='4611688150860241903' />
<permission memberid='9' mask='1856436900863' />
<permission memberid='10' mask='206292848673' />
<permission memberid='11' mask='206292717568' />
<permission memberid='13' mask='756052856897' />
<permission memberid='1073741823' mask='206292717568' />
</permissions>
********* End of Role Assignments Xml

**** End Miscellaneous for List Item


*** File default.aspx content:

???<%@ Page Inherits="Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %> <%@ Reference VirtualPath="~TemplatePageUrl" %> <%@ Reference VirtualPath="~masterurl/custom.master" %>

<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"><head>

<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>

<mso:ContentType msdt:dt="string">Welcome Page</mso:ContentType>

<mso:PublishingPageLayout msdt:dt="string">/_catalogs/masterpage/searchmain.aspx, Search Page</mso:PublishingPageLayout>

</mso:CustomDocumentProperties>
</xml><![endif]-->

<title>Search Center</title></head>


*** End File
*** Anonymous has rights on File default.aspx: [True]

 

The code core is below. The cascade walking class was based on Sanjay’s class defined at http://blogs.msdn.com/b/sanjaynarang/archive/2009/04/07/find-sharepoint-object-type-from-url.aspx .

You can download code and executable here: http://rodneyviana.codeplex.com/releases/view/19103

It works for SharePoint 2010 but you have to change the references and recompile using 14.x assemblies.

 

 

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Deployment;

namespace CheckEffectiveProperties
{
    public class SPObjType
    {
        public Guid objectGuid;
        public object obj;
        public string url;
        public string siteRelativeUrl;
        public SPDeploymentObjectType objType;
        public StringBuilder message = new StringBuilder(2000);
        public SPBasePermissions currUserRights;
        public SPBasePermissions testUser;
        public SPBasePermissions anonymousMask;
        public bool? isAnonymousEnabled = null;

       
        public static string EnumeratePermission(SPBasePermissions Mask)
        {
            StringBuilder sb = new StringBuilder(100);
            sb.AppendFormat("Perm Mask  -  Hex: {0} Binary {1}\n", ((ulong)Mask).ToString("x8"), Convert.ToString((Int64)Mask, 2));
            foreach (string permName in Enum.GetNames(typeof(SPBasePermissions)))
            {
                ulong i = (ulong)Mask & (ulong)(Enum.Parse(typeof(SPBasePermissions), permName));
                if (i > 0)
                {
                    sb.Append(String.Format("    {0} Hex [{1}] Binary [{2}]\n", permName, i.ToString("x8"),  Convert.ToString((Int64)i, 2)));
                }
            }
            return sb.ToString();
        }
        public void GetFile(SPFile File, SPBasePermissions Mask)
        {
            try
            {
                byte[] binFile = File.OpenBinary();
                ASCIIEncoding asc = new ASCIIEncoding();
                string fileContent = asc.GetString(binFile);
                message.AppendFormat("\n*** File {0} content:\n\n{1}\n\n", File.Name, fileContent);
                message.Append("\n*** End File");
                if (File.Item != null)
                {
                    message.AppendFormat("\n*** Anonymous has rights on File {0}: [{1}]\n\n", File.Name, File.Item.DoesUserHavePermissions(Mask));
                }
                else
                {
                    message.AppendFormat("\n*** Unable to test Anonymous rights on File {0}\n\n", File.Name);
                }
            }
            catch (Exception ex)
            {
                message.AppendFormat("\n\n***************  Error opening file {0}: {1}  ************\n\n", File.Name, ex.Message);
               
            }

        }
    }


    // The class below was originally created by Sanjay Narang to identify the object type from a URL
    // The code for this intent is found here:
http://blogs.msdn.com/b/sanjaynarang/archive/2009/04/07/find-sharepoint-object-type-from-url.aspx
    //
    // It was modified to check properties and cascade access (Anonymous | Current User | GivenUser)
    //    for an object pointed by Rodney Viana
    // You have to agree with this license to use this code/application:
http://rodneyviana.codeplex.com/license
    // Details of the implementation can be found at: http://blogs.msdn.com/rodneyviana
    // This project can be downloaded at: http://rodneyviana.codeplex.com/releases/view/19103

    class SanjayMossUtilities
    {
        public SPObjType GetObjectTypeFromURL(string passedUrl, string User)
        {
            SPObjType oType = new SPObjType();
            oType.objType = SPDeploymentObjectType.Invalid;

            oType.objectGuid = Guid.Empty;

            SPSite site = null;
            SPWeb web = null;
            SPList list = null;
            oType.obj = null;
            oType.url = null;
            oType.siteRelativeUrl = null;
            NameValueCollection queryParams = null;

            oType.url = GetModifiedUrl(passedUrl, out queryParams);

            try
            {
                site = new SPSite(oType.url);
                oType.message.AppendFormat("**** Start Miscellaneous for Site {0}\n", site.Url);
                oType.message.AppendFormat("IIS Allow Anonymous:  [{0}]\n", site.IISAllowsAnonymous);
                oType.message.AppendFormat("IIS is impersonating: [{0}]\n", site.Impersonating);
                oType.message.AppendFormat("Zone:                 [{0}]\n", site.Zone.ToString());
                oType.message.AppendFormat("Host Name:            [{0}]\n", site.HostName);
                oType.message.AppendFormat("Write Locked:         [{0}]\n", site.WriteLocked);
                oType.message.Append("**** End Miscellaneous for Site\n");

                web = site.OpenWeb();
                oType.message.AppendFormat("**** Start Miscellaneous for Web {0}\n", web.Url);
                oType.message.AppendFormat("Web Allow Anonymous:  [{0}]\n", web.AllowAnonymousAccess);
                oType.message.AppendFormat("Anonymous Access to Lists and Libraries:  [{0}]\n", web.AnonymousState.ToString());
                if (web.AllowAnonymousAccess)
                {
                    oType.message.Append("********* Start of List of Rights to anonymous in this web\n");
                    oType.message.Append(SPObjType.EnumeratePermission(web.AnonymousPermMask64));
                    oType.message.Append("********* End of List of Rights to anonymous in this web\n\n");
                }

                if (!String.IsNullOrEmpty(User))
                {
                    oType.message.AppendFormat("********* Start of List of Rights for User {0}\n", User);
                    oType.message.Append(SPObjType.EnumeratePermission(web.GetUserEffectivePermissions(User)));
                    oType.message.Append("********* End of List of Rights\n\n");

                }
                string curUser = Environment.UserDomainName + "\\" + Environment.UserName;
                if (User.ToLower().Trim() != curUser.ToLower().Trim())
                {
                    oType.message.AppendFormat("********* Start of List of Rights for Current User {0}\n", curUser);
                    oType.message.Append(SPObjType.EnumeratePermission(web.GetUserEffectivePermissions(curUser)));
                    oType.message.Append("********* End of List of Rights\n\n");
                }
                oType.message.Append("**** End Miscellaneous for Web\n\n");
               


                if (oType.url.Equals(site.Url, StringComparison.OrdinalIgnoreCase))
                {
                    oType.objectGuid = site.ID;
                    oType.objType = SPDeploymentObjectType.Site;
                   
                    return oType;
                }

                if (oType.url.Equals(web.Url, StringComparison.OrdinalIgnoreCase))
                {
                    oType.objectGuid = web.ID;
                    oType.objType = SPDeploymentObjectType.Web;
                    return oType;
                }

                oType.siteRelativeUrl = oType.url.TrimStart(web.Url.ToCharArray());

                try
                {
                    list = web.GetList(oType.url);
                }
                catch(Exception ex)
                {
                    oType.message.AppendFormat("\n\n  *******  Error trying to retrieve List : {0}  ***** \n\n", ex.Message);
                    list = null;
                }
     


                if (null != list )
                {
                    oType.objectGuid = list.ID;
                    oType.objType = SPDeploymentObjectType.List;

                    oType.message.AppendFormat("**** Start Miscellaneous for List {0} at {1}\n", list.Title, list.DefaultViewUrl);
                    oType.message.AppendFormat("Access to Template List is Restricted     :  [{0}]\n", list.RestrictedTemplateList);
                    oType.message.AppendFormat("Users Access Limited to Items they Created:  [{0}]\n", (list.ReadSecurity==2));
                    oType.message.AppendFormat("Anonymous can access                      :  [{0}]\n", list.DoesUserHavePermissions(list.AnonymousPermMask64));
                    oType.message.AppendFormat("Everyone can view List                    :  [{0}]\n", list.AllowEveryoneViewItems);


                    oType.message.Append("********* Start of List of Rights to anonymous in this List\n");
                    oType.message.Append(SPObjType.EnumeratePermission(list.AnonymousPermMask64));
                    oType.message.Append("********* End of List of Rights to anonymous in this List\n\n");

                    if (!String.IsNullOrEmpty(User))
                    {
                        oType.message.AppendFormat("********* Start of List of Rights for User {0}\n", User);
                        oType.message.Append(SPObjType.EnumeratePermission(list.GetUserEffectivePermissions(User)));
                        oType.message.Append("********* End of List of Rights\n\n");

                    }
                    if (User.ToLower().Trim() != curUser.ToLower().Trim())
                    {
                        oType.message.AppendFormat("********* Start of List of Rights for Current User {0}\n", curUser);
                        oType.message.Append(SPObjType.EnumeratePermission(list.GetUserEffectivePermissions(curUser)));
                        oType.message.Append("********* End of List of Rights\n\n");
                    }
                    oType.message.Append("**** End Miscellaneous for List\n\n");

                    if (oType.siteRelativeUrl.Equals(list.RootFolder.Url, StringComparison.OrdinalIgnoreCase))
                    {
                        return oType;
                    }
                }

                // if we are here, it means URL is none of these:
                // site, web, list
                // So, it can be either file, folder or a list item.
                // Finding that is intricated.

                oType.obj = web.GetObject(oType.url);

                if (null != oType.obj)
                {
                    SPListItem item = (oType.obj as SPListItem);
                    if (item != null)
                    {
                        if (!String.IsNullOrEmpty(User))
                        {
                            oType.message.AppendFormat("**** Start Miscellaneous for List Item {0} at {1}\n", item.Name, item.Url);
                            oType.message.AppendFormat("Anonymous has access to list item    :  [{0}]\n", item.DoesUserHavePermissions( list.AnonymousPermMask64));
                            oType.message.AppendFormat("Permission Inheritance is broken     :  [{0}]\n", item.HasUniqueRoleAssignments);


                            //                    oType.message.Append(SPObjType.EnumeratePermission(web.AnonymousPermMask64));

                            oType.message.AppendFormat("********* Start of List of Rights for User {0}\n", User);
                            oType.message.Append(SPObjType.EnumeratePermission(item.GetUserEffectivePermissions(User)));
                            oType.message.Append("********* End of List of Rights\n\n");

                        }
                        if (User.ToLower().Trim() != curUser.ToLower().Trim())
                        {
                            oType.message.AppendFormat("********* Start of List of Rights for Current User {0}\n", curUser);
                            oType.message.Append(SPObjType.EnumeratePermission(item.GetUserEffectivePermissions(curUser)));
                            oType.message.Append("********* End of List of Rights\n\n");
                        }
                        oType.message.AppendFormat("********* Item Xml\n", curUser);
                        oType.message.AppendFormat("{0}\n", item.Xml);

                        oType.message.Append("********* End of Item XML\n\n");
                        oType.message.AppendFormat("********* Role Assignments Xml\n", curUser);
                        oType.message.AppendFormat("{0}\n", item.RoleAssignments.Xml);

                        oType.message.Append("********* End of Role Assignments Xml\n\n");


                        oType.message.Append("**** End Miscellaneous for List Item\n\n");
                       
                    }
                    if (oType.obj is SPFile)
                    {
                        // Generally, we get here for Forms Pages,
                        // such as DispForm.aspx, AllItems.aspx
                        // so, a SPFile object could be a list item Or
                        // a folder in a list or a Folder

                        // Pages in root of the web are also returned as
                        // SPFiles e.g.
http://moss/default.aspx

                        // The URLs that point to a file in doc lib are
                        // returned as SPListItem by GetObject method
                        //

                        SPFile file = oType.obj as SPFile;

                        if (null != queryParams)
                        {
                            // The logic to identify folder or item has
                            // been explained in ValidateQueryString
                            string idValue = queryParams["ID"];
                            string folderValue = queryParams["RootFolder"];
                            if (null != idValue)
                            {
                                item = list.GetItemById(int.Parse(idValue));
                                oType.objectGuid = item.UniqueId;
                                oType.objType = SPDeploymentObjectType.ListItem;
                                return oType;
                            }
                            else if (null != folderValue)
                            {
                                SPFolder folder = web.GetFolder(folderValue);
                                oType.objectGuid = folder.UniqueId;
                                oType.objType = SPDeploymentObjectType.Folder;
                                return oType;
                            }
                            else
                            {
                                // Deployyment Object Type is: Invalid, so no need
                                // to do anything
                            }
                        }
                        else
                        {
                            oType.objectGuid = file.UniqueId;
                            oType.objType = SPDeploymentObjectType.File;
                            oType.GetFile(file, web.AnonymousPermMask64);
                            return oType;
                        }
                    }
                    else if (oType.obj is SPFolder)
                    {
                        SPFolder folder = oType.obj as SPFolder;
                        oType.objectGuid = folder.UniqueId;
                        oType.objType = SPDeploymentObjectType.Folder;
                        return oType;
                    }
                    else if (oType.obj is SPListItem)
                    {

                        item = oType.obj as SPListItem;

                        // item can contain a folder of file also. e.g.
                        //
http://moss.litwareinc.com/Documents/folderinlibrary
                        // http://moss.litwareinc.com/Documents/FolderInLibrary/File2.doc

                        if (null != item.Folder)
                        {
                            oType.objectGuid = item.Folder.UniqueId;
                            oType.objType = SPDeploymentObjectType.Folder;
                            return oType;
                        }
                        else if (null != item.File)
                        {
                            oType.objectGuid = item.File.UniqueId;
                            oType.objType = SPDeploymentObjectType.File;
                            oType.GetFile(item.File, web.AnonymousPermMask64);

                            return oType;
                        }

                        oType.objectGuid = item.UniqueId;
                        oType.objType = SPDeploymentObjectType.ListItem;
                        return oType;
                    }
                }

            }
            finally
            {
                if (web != null)
                {
                    web.Dispose();
                }
                if (site != null)
                {
                    site.Dispose();
                }
            }
            return oType;
        }

        private string GetModifiedUrl(string url, out NameValueCollection queryParams)
        {
            string modUrl = url; //modified url
            string querystring = string.Empty;
            queryParams = null;

            // if it's a site or web or folder, user can pass '/' at
            // the end, which we need to trim
            if (url.EndsWith("/"))
            {
                modUrl = url.TrimEnd(new char[] { '/' });
            }

            // we need to get the URL without query string as it creates
            // problem getting the parent folder
            if (url.Contains("?"))
            {

                int tmp = url.IndexOf("?");
                modUrl = url.Substring(0, tmp);
                querystring = url.Substring(tmp + 1);

                queryParams = HttpUtility.ParseQueryString(querystring);
                // apply custom rules
                ValidateQueryString(queryParams);
            }

            return modUrl;
        }

        private void ValidateQueryString(NameValueCollection queryParams)
        {
            // when there's query string in the URL, the URL can point to a
            // list item (in a list) or a folder.          
            // For example if an item is a folder
            // 'FolderInTasksList' the URL of item would look like this   
            //
http://moss.litwareinc.com/Lists/Tasks/DispForm.aspx?ID=2&RootFolder=/Lists/Tasks/FolderInTasksList OR
            //
http://moss.litwareinc.com/Lists/Tasks/DispForm.aspx?ID=2&RootFolder=%2fLists%2fTasks%2fFolderInTasksList
            //
            // And if we need Url of the folder, it would be like this:
            //
http://moss.litwareinc.com/Lists/Tasks/AllItems.aspx?RootFolder=%2fLists%2fTasks%2fFolderInTasksList&FolderCTID=&View=%7bD8E1251D%2d829B%2d4FCE%2d9127%2d5E4FC6E6A5C4%7d
            //
            // From the above two examples, I'm applying the following
            // rules on the query string
            // 1. It can contain only these keys: ID, RootFolder, FolderCTID, View
            //    If there's any other key, i would treat that as invalid query string
            //
            // 2. ID and RootFolder should never be empty
            //    otherwise, raise exception here rather than hitting that later
            //
            // 3. the query string has to contain at least one of the following
            //    a. ID, b. RootFolder

            // Build a string collection with possible values. For comparison,
            // we'll use lower case only
            StringCollection strColl = new StringCollection();
            strColl.Add("ID".ToLower());
            strColl.Add("RootFolder".ToLower());
            strColl.Add("FolderCTID".ToLower());
            strColl.Add("View".ToLower());

            // Apply the Rules
            bool hasID = false;
            bool hasRootFolder = false;

            Console.WriteLine();
            foreach (string str in queryParams.AllKeys)
            {
                // can be used for debugging
                // Console.WriteLine("Name: " + str + " | Value: " + queryParams[str]);

                // Rule 1
                if (!(strColl.Contains(str.ToLower())))
                {
                    throw new ArgumentException("Invalid argument in passed query string");
                }
                // Rule 2
                if (str.Equals("id", StringComparison.OrdinalIgnoreCase))
                {
                    hasID = true;
                    if (queryParams[str].Equals(String.Empty))
                    {
                        throw new ArgumentException("Query string parameter \"" + str + "\" can not be empty.");
                    }
                }
                // Rule 2
                if (str.Equals("rootfolder", StringComparison.OrdinalIgnoreCase))
                {
                    hasRootFolder = true;
                    if (queryParams[str].Equals(String.Empty))
                    {
                        throw new ArgumentException("Query string parameter \"" + str + "\" can not be empty.");
                    }
                }
            }
            // Rule 3
            Console.WriteLine();
            if (!(hasID || hasRootFolder))
            {
                throw new ArgumentException("Query string must have at least one parameter from these: ID and RootFolder");
            }
        }

    }
}