Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

Solution

Check to see if your assembly received the optional permissions using the
SecurityManager.IsGranted method like this:
using System;
using System.Text.RegularExpressions;
using System.Web;
using System.Net;
using System.Security;

Regex regex = new Regex(@"http://www\.oreilly\.com/.*");


WebPermission webConnectPerm = new WebPermission(NetworkAccess.
Connect,regex);
if(SecurityManager.IsGranted(webConnectPerm))
{
// Connect to the O'Reilly site.
}

This code sets up a Regex for the O’Reilly web site and then uses it to create a
WebPermission for connecting to that site and all sites containing the string. You then
check the WebPermission by calling SecurityManager.IsGranted to see whether you
have permission to do this.

Discussion
The IsGranted method is a lightweight way of determining whether permission is
granted for an assembly without first incurring the full stackwalk that a Demand gives
you. Note, however, that once you exercise the code that performs the Demand, the
full stackwalk will then take place. The drawback to this approach is that the code is
still subject to a luring attack if Assert is misused, so you need to consider where the
call to IsGranted is being made in the overall scheme of your security.
Some of the reasons you might design an assembly to have optional permissions is
for deployment in different customer scenarios. In some scenarios (such as desktop
applications), it might be acceptable to have an assembly that can perform more
robust actions (talk to a database, create network traffic via HTTP, etc.). In other
scenarios, you can defer these actions if the customer does not wish to grant enough
permissions for these extra services to function.

See Also
The “WebPermission Class,” “SecurityManager Class,” and “IsGranted Method”
topics in the MSDN documentation.

686 | Chapter 17: Security


HashSet<T> object, 444–448 %SystemDrive% environment variable, 469
inheritance and, 70 SystemEvents class
interfaces and, 69, 135 change notifications, 771–775
multiple return values and, 104 DisplaySettingsChanged event, 774
n-ary trees, 432–444 DisplaySettingsChanging event, 774
one-to-many maps, 410–418 EventsThreadShutdown event, 771, 774
passing by value, 69 InstalledFontsChanged event, 774
performance and, 68, 70 OnEventsThreadShutdown handler, 772
polymorphism and, 69, 70 OnPowerModeChanged method, 772
priority queues, 402–410 OnSessionEnded handler, 772
reference types and, 68 OnSessionEnding handler, 772
union-type, 70–72 OnSessionSwitch handler, 772
usage recommendations, 69 PaletteChanged event, 774
ValueType class and, 68 PowerModeChanged event, 771, 774
Subgroup class, 227, 229 RegisterForSystemEvents method, 771,
subset operation, 446, 447 772
subtraction operator, 80–82 SessionEnded event, 771, 774
Sum function, 28 SessionEnding event, 771, 774
superset operation, 446, 447 SessionSwitch event, 771, 774
svchost process, 291 TimeChanged event, 774
SwapElementsInArray method, 177 TimerElapsed event, 774
switch statement, 777, 808, 809 UnregisterFromSystemEvents
SymmetricAlgorithm class method, 771, 772
Clear method, 131, 670–672 UserPreferenceChanged event, 774
encrypting/decrypting files, 665–670 UserPreferenceChanging event, 774
SymmetricExceptWith method, 447 SystemException class, 246, 261
synchronization
multiple processes, 738–750 T
thread, 721–725
tab character, 65
synchronous delegates, 327–330
tables
System processes, 780
accessing, 18
System.Attribute, 236
tying to cache, 530–531
System.CLSCompliantAttribute, 234
TakeSnapshotOfList<T> method, 198, 199
System.Collections namespace, 175
TargetInvocationException exception, 252,
System.Collections.ArrayList type, 331
253
System.Collections.Generic namespace, 175
TaskManager, 290–292
System.Collections.Specialized
TCP (Transmission Control Protocol)
namespace, 175–176
securing stream data, 699–708
System.Configuration assembly, 21
writing TCP clients, 612–615
System.Cryptography namespace, 665
writing TCP servers, 606–611
System.Diagnostics namespace, 286
TcpClient class
System.IO.Pipes namespace, 622
Close method, 131, 611
System.Messaging.MessageQueue class (see
Connect method, 615
MessageQueue class)
GetStream method, 609
System.Reflection.Emit namespace, 501
Read method, 615
System.Runtime.Remoting.Messaging
SslStream class and, 705
namespace, 328
Write method, 615
System.SerializeableAttribute, 234
writing TCP clients, 612–615
System.Text namespace, 56, 58
TCPClient_SSL class, 699–701
System.Text.RegularExpressions
TcpListener class
namespace, 36, 366
AcceptTcpClient method, 607, 611
System.Xml.XPath namespace, 555
Start method, 611

Index | 851
Finally, you have a method that calls the CreatePoint method. This method handles
the point object type returned from the CreatePoint method based on the actual
point object returned:
public void CreateAndHandlePoint( )
{
// Create a new point object and return it.
object retObj = CreatePoint(PointTypeEnum.Point2D);

// Handle the point object based on its actual type.


if (retObj is ExPoint2D)
{
Console.WriteLine("Use the ExPoint2D type");
}
else if (retObj is ExPoint3D)
{
Console.WriteLine("Use the ExPoint3D type");
}
else if (retObj is Point2D)
{
Console.WriteLine("Use the Point2D type");
}
else if (retObj is Point3D)
{
Console.WriteLine("Use the Point3D type");
}
else
{
Console.WriteLine("Invalid point type");
}
}

Notice that the tests for the ExPoint2D and ExPoint3D objects are performed before
the tests for Point2D and Point3D. This order will allow you to differentiate between
base classes and their derived classes (ExPoint2D derives from Point2D and ExPoint3D
derives from Point3D). If you had reversed these tests, the test for Point2D would eval-
uate to true for both the Point2D class and its derivatives (ExPoint2D).

Discussion
The is operator is a fast and easy method of predetermining whether a cast will
work. If the cast fails, you have saved yourself the overhead of trying the cast and
handling a thrown exception. If the is operator determines that this cast can success-
fully be performed, all you need to do is perform the cast.
The is operator is defined as follows:
expression is type

102 | Chapter 3: Classes and Structures


Example 15-7. Invoice.xml (continued)
<price>35.98</price>
<shipDate>2003-12-20</shipDate>
</item>
<item partNum="AK254">
<productName>Job Site Ale</productName>
<quantity>50</quantity>
<price>12.56</price>
<shipDate>2003-11-12</shipDate>
</item>
</Items>
</Invoice>

How to tear this invoice apart using an XElement and send the various information
pieces to their respective departments is shown in Example 15-8.

Example 15-8. Tearing apart an XML document (XElement)


public static void ProcessInvoice( )
{
XElement invElement = XElement.Load(@"..\..\Invoice.xml");
// Process the billing information to Accounting
CreateInvoiceEnvelope(invElement, "BillingEnvelope", "billInfo",
@"..\..\BillingEnvelope_LINQ.xml");

// Process the shipping information to Accounting


CreateInvoiceEnvelope(invElement, "ShippingEnvelope", "shipInfo",
@"..\..\ShippingEnvelope_LINQ.xml");

// Process the item information to Fulfillment


CreateInvoiceEnvelope(invElement, "FulfillmentEnvelope", "Items/item",
@"..\..\FulfillmentEnvelope_LINQ.xml");
}

private static void CreateInvoiceEnvelope(XElement invElement,


string topElementName,
string internalElementName,
string path)
{
var query = from i in invElement.DescendantsAndSelf( )
where i.NodeType == XmlNodeType.Element &&
i.Name == "Invoice"
select new XElement(topElementName,
new XAttribute(i.Attribute("invoiceDate").Name,
i.Attribute("invoiceDate").Value),
new XAttribute(i.Attribute("invoiceNumber").Name,
i.Attribute("invoiceNumber").Value),
from e in i.XPathSelectElements(internalElementName)
select new XElement(e));
XElement envelope = query.ElementAt<XElement>(0);
Console.WriteLine(envelope.ToString( ));
// save the envelope
envelope.Save(path);
}

580 | Chapter 15: XML


The full version number is comprised of these four parts, making up an 8-byte num-
ber representing the file’s version number.
The CompareFileVersions method first compares the FileMajorPart version informa-
tion of the two files. If these are equal, the FileMinorPart version information of the
two files is compared. This continues through the FileBuildPart and finally the
FilePrivatePart version information values. If all four parts are equal, the files are
considered to have the same version number. If either file is found to have a higher
number than the other file, it is considered to be the latest version.

See Also
The “FileVersionInfo Class” topic in the MSDN documentation.

12.14 Querying Information for All Drives on a System


Problem
Your application needs to know if a drive (HDD, CD drive, DVD drive, etc.) is avail-
able and ready to be written to and/or read from. Additionally, it would be nice to
know if you have enough available free space on the drive to write information to.

Solution
Use the various properties in the DriveInfo class as shown here:
public static void DisplayAllDriveInfo( )
{
foreach (DriveInfo drive in DriveInfo.GetDrives( ))
{
if (drive.IsReady)
{
Console.WriteLine("Drive " + drive.Name + " is ready.");
Console.WriteLine("AvailableFreeSpace: " + drive.AvailableFreeSpace);
Console.WriteLine("DriveFormat: " + drive.DriveFormat);
Console.WriteLine("DriveType: " + drive.DriveType);
Console.WriteLine("Name: " + drive.Name);
Console.WriteLine("RootDirectory.FullName: " +
drive.RootDirectory.FullName);
Console.WriteLine("TotalFreeSpace: " + drive.TotalFreeSpace);
Console.WriteLine("TotalSize: " + drive.TotalSize);
Console.WriteLine("VolumeLabel: " + drive.VolumeLabel);
}
else
{
Console.WriteLine("Drive " + drive.Name + " is not ready.");
}
}
}

Querying Information for All Drives on a System | 479

You might also like