Does cleaning Prefetch offers more performance?

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

It has been always said that when you clean the folder %windir%Prefetch you give your system and applications more performance.

Actually, thats one of the fables around Windows. Each time you start your computer and each time you open a program that you commonly use, Windows keeps track of information required to start the computer or that application and saves theses information in small files (called Prefetch entries) in the Prefetch folder to use it later to help speed up the computer start process or the application start time.

Thus, cleaning the Prefetch folder doesnt improve performance at all. Instead, it slows it down. It makes Windows uses longer time to start, and makes your favorite programs take longer time opening. An analysis did by TuneUp Systems results in a noticeable slowdown during Windows boot-up time and all applications that are commonly used took significantly longer to start after cleaning Prefetch.

Obviously, you do not need to deal with Prefetch entries manually, Windows handles them all. Actually, Windows Vista (and future systems that support UAC) helps protecting the Prefetch folder by using UAC (User Access Control, read more here) to prevent unauthorized access to this folder.

Requesting Admin Approval at Application Start

Introduction

User Access Control (UAC) is a feature of Windows that can help prevent unauthorized changes to your computer. UAC does this by asking you for permission or an administrator password before performing actions that could potentially affect your computer’s operation or that change settings that affect other users.

With UAC, Administrator users, by default, don’t have administrative privileges. Every Windows process has two security tokens associated with it, one with normal user privileges and one with admin privileges. With applications that require administrative privileges, the user can change the application to run with Administrator rights. And that process called Elevation.

Therefore, when a normal user logs on to the system he assigned the standard user access security token that does not allow him to access administrator resources. On the other hand, when an administrator logs on to the system, Windows creates two security tokens for him: a standard user access token and an administrator access token. And he assigned the latter. When he tries to access a resource requires administrator privileges, he is asked for elevation. Unless he approved the elevation request, he cannot access that resource. It is worth mentioning that standard users cannot access protected resources. However, they are requested for the elevation, by entering an administrator username and password. Therefore, the administrator accesses the protected resource on behalf of the standard user.

Now, there is a question. Why I need administrator privileges? Means, what are the resources that are protected? The answer is very simple. Most operations that may affect the system or other users on the machine are access protected. For example, writing a file on the system drive requires admin approval, reading from the registry requires admin approval, and changing file association requires admin approval.

After all, in this lesson, we will learn how to request admin approval at the application start to allow the application to access protected administrator resources.

Requesting Admin Approval via a Manifest

To request the admin approval, you can need to embed a manifest with specific form to the application.

An application manifest is an XML file similar to the application configuration file but it has another construction.

To embed a manifest to the application, you will need to add it to the project and ask Visual Studio to embed it.

The Manifest Construction

The following is the manifest construction:

Download this file here.


    
    
        
            
                
            
        
    

You can also add this manifest file via the Add New Item dialog. However, VB.NET adds it automatically. But be sure to edit it.

This manifest should be named the way you name the configuration file. That means that its name should be app.manifest, so Visual Studio can treat it the right way.

This manifest is nothing more than a simple XML file with a specific construction. You cannot change any element name or a namespace. However, you can set the application required privileges through the attributes level and uiAccess of the requestedExecutionLevel element.

The level attribute specifies the security level that we need to grant the application. It can be one of three values:

  • requireAdministrator:
    Means that the application requires administrator privileges (elevation, in other words.) If this is an administrator, he will be asked for approval. If this is a standard user, he will be asked to provide an administrator’s username and password. Therefore, the administrator executes the application of behalf of the standard user.
  • highestAvailable:
    The application gets the privileges the user has but only after getting the consent from the user. Means that if the user is a standard user, the application gets standard user privileges. On the other hand, if the user is an administrator, the application gets the admin privileges but after the request for elevation.
  • asInvoker:
    The application is running with the security token of the user. Means that if the user is a standard user or an administrator, the application gets the standard user privileges without elevation, and does not request it.

While VB.NET automatically adds the manifest file, it sets requestedExecutionLevel to asInvoker.

The uiAccess option comes handy if your application requires input to a higher-privilege-level window on the desktop. For example, if your application is an onscreen keyboard. Set uiAccess to true to allow that type of input, or false otherwise.

Actually, you will not be granted the UIAccess privilege unless your application is installed in a secure location like the Program Files directory. If you need to allow all applications located in any place to be granted the UIAccess privilege, you will need to change system policy in the Local Security Policy MMC snap-in. Lean more here.

Automatically Creating the Manifest

To embed the manifest to your application, follow these steps:

  1. Add the manifest file (app.manifest) to the project.
  2. Open the Project Properties dialog.
  3. Switch to the Application tab.
  4. In the Resources section and in the Manifest field, you can choose to embed a default manifest to the application that has the asInvoker level set, to create the application without a manifest and that has the same effect as the previous option, or to choose from a list of manifest files added to the project.

Figure 1 shows how to embed the manifest file.

Figure 1. Embedding a Manifest
Figure 1. Embedding a Manifest

Trying the Example

Now, we are going to write a simple example illustrates how to request admin approval at the application how this affects the application progress.

For the example to work well, it is better not to start Visual Studio .NET with admin privileges because if you ran the application from the Visual Studio environment, it will be granted its permissions automatically. However, to see the results, run the application from its file.

Now, start a new project and add the following code to the Main() function:

static void Main()
{
    // Change the drive C to
    // the system drive
    System.IO.File.WriteAllText("C:\MyFile.txt", "Hello, World");
    Console.WriteLine("Completed");
    Console.ReadKey(true);
}

The last code tries to write a file to the system drive which is access protected and requires admin approval to allow the writing.

Now, try to run the application. Unfortunately, because you are not granted the administrator access token, the application will be failed you will be faced with System.UnauthorizedAccessException.

Again, if you started Visual Studio .NET with admin privileges, you will not see how the UAC affects the whole application. In that case, you will need to run the application from its file.

Now, add the manifest to the application and embed it and try to run the application again.

Cheers, succeeded. Now, you are faced with the admin approval message. The following figures show the two types of admin approval messages. Figure 2 shows the prompt for consent message for administrator users, while figure 3 shows the prompt for credentials message for standard users.

Figure 2. Prompt for Consent Message
Figure 2. Prompt for Consent Message
Figure 3. Prompt for Credentials Message
Figure 3. Prompt for Credentials Message

Requesting Admin Approval via the Registry

While you can easily request admin approval via a manifest file during the development process, it will not be the case if the application already deployed.

Actually, you can request an application to start with admin privileges by right-clicking the application file and choosing €œRun as Administrator€ item. However, you will need to do this every time you try to run the application.

Another way is to change the application to request admin approval every time you execute it. This is done through the compatibility options in the Properties dialog of the application file. See figure 4.

Figure 4. Compatibility Options
Figure 4. Compatibility Options

Setting this option adds the compatibility flag RUNASADMIN to the registry at SOFTWAREMicrosoftWindows NTCurrentVersionAppCompatFlagsLayers that resides in HKCU if you change current user settings or HKLM if you choose to change the settings for all users. Figure 5 shows our application item in the registry.

Figure 5. Compatibility Flags in Registry
Figure 5. Compatibility Flags in Registry

Therefore, you can register an application to run as administrator if you added the compatibility flag RUNASADMIN in the right place.

Actually, you can replace the manifest approach with this way. You make the application installer add this compatibility flag in the installation process which is -by default- runs in admin privileges mode.

The Last Word

It is worth mentioning that this does not apply to Windows Vista only, it applies to Windows 7 -and maybe later versions- also. Working with UAC is very exhausting. However, you should relax! Windows 7 fixes major UAC problems. Now, you are not required to grant the permission for such these simple operations like changing system date and time.

It is worth mentioning that it is better not to request admin approval for the whole application. It is recommended that you request admin approval for the specific operations that require it only. And this can be done through the Windows Vista SDK.

In addition, you can read more about UAC and how it affects your application flow in these articles:

Good day!

Download Vista Bridge Sample Library 1.4

The Vista Bridge Sample Library contains source code for assemblies that provide managed code developers access to Windows Vista features that are not available in the .NET Framework. Some of the features included in the Vista Bridge Sample Library are – Vista style Task and File Dialogs, Common Open and Save dialogs, Application Recovery and Restart, Known Folders, Network Lists, Power Management, User Account Control, CommandLink control, Aero Wizard Control, System provided icons etc.

The Vista Bridge Sample Library also includes sample applications that demonstrate many of the features included in the library. A help file for the library, (vistabridgedocumentation.chm), is included.

The latest version (1.4) of this library includes various bug fixes and new features like Custom Controls for Common File Dialogs, BreadCrumb bar control and Aero Glass.

To build the library in Visual Studio 2008, please extract the contents of the ‘VistaBridge1.4.zip’ file in a new folder, open the included ‘vistabridge.sln’ file and build it.

Download from HERE

Advanced Control of UAC

Here in this lesson we’ll learn some useful techniques for controlling the UAC (User Access Control.)

What is User Access Control?

User Access Control (UAC) is a feature of Windows that can help prevent unauthorized changes to your computer. UAC does this by asking you for permission or an administrator password before performing actions that could potentially affect your computer’s operation or that change settings that affect other users.

By default, Administrator users do not have administrative privileges. Every Windows process has two security tokens associated with it, one with normal user privileges and one with admin privileges. With applications that require administrative privileges, the user can elevate the application to run with Administrator rights. And that process called Elevation.

User can elevate an application either by clicking “Run as Administrator” from the context menu of the application icon, or by editing the Compatibility tab in the properties of the application file.
Also, while an application running, it can ask the user to provide administrative permission to complete a specific operation (a good example is switching to the All Users mode in Task Manager.)

Compatibility Options
Compatibility Options

Disabling or enabling UAC

You can disable or enable the UAC simply from the Control Panel from the User Accounts configuration.

Enabling-Disabling UAC
Enabling/Disabling UAC

By clicking the “Turn UAC on or off” option you can disable or enable the UAC.

Advanced Control of UAC

You can control every aspect of UAC using the Local Security Policy MMC snap-in. You can open this snap in from Administrative Tools in the Control Panel.

After opening Local Security Policy utility, step down to the Local Policies then to the Security Options node.

From the right you can find a list of security policies that you can take control of.

Advanced UAC
Local Security Policy - Advanced UAC

We are interested on the nine policies that are applied to the UAC, and these policies are:

Admin Approval Mode for the Built-in Administrator account

This policy specifies whether to enable Admin Approval Mode for the built-in Administrator account or not.

Admin Approval Mode means requiring the user via the UAC messages to approve administrative operations. In other words, it means enabling the elevation process.

This policy is disabled by default.

Behavior of the elevation prompt for administrators in Admin Approval Mode

This policy defines the behavior for the administrators while in Admin Approval Mode (while the previous policy is enabled.)

You can set this policy to one of three options:

  • Prompt for consent (default):
    Ask the user to provide the permission by clicking either Allow button (sometimes Continue) or Cancel button.
  • Prompt for credentials:
    Ask the user to enter his password.
  • Elevate without prompting:
    Grant the permission without asking the user.
Prompt for Consent Message
Prompt for Consent Message
Prompt for Credentials Message
Prompt for Credentials Message

Behavior of the elevation prompt for standard users

This policy defines the behavior for standard users (non-Administrator users) while elevation.

This policy can have one of two options:

  • Prompt for credentials (the default for home editions):
    Asking the user to provide administrator username and password.
  • Automatically deny elevation requests (the default for enterprise editions):
    Do not ask the user and automatically deny the elevation request.

Detect application installations and prompt for elevation

This policy defines whether to prompt for elevation for application installations or to allow them without asking.
By default, this policy is enabled for home editions, and disabled for enterprise editions.

Only elevate executables that are signed and validated

This policy defines whether to elevate only the applications from known vendors (like Microsoft of course), or prompting for elevation for all applications.

This policy is disabled by default.

Only elevate UIAccess applications that are installed in secure locations

If the application requests execution with the UIAccess integrity level, this policy defines whether to allow the application if it resides in secure locations (like Program Files), or not.

This policy is enabled by default.

Run all administrators in Admin Approval Mode

This policy defines the behavior of all UAC policies for the entire system.

If this policy is enabled, all administrators will run in Admin Approval Mode and you will be asked for elevation. Conversely, if this policy is disabled, then all administrators will be granted the permission by default.

This policy is enabled by default.

Switch to the secure desktop when prompting for elevation

This policy defines whether all elevation requests will go to the Secure Desktop or the Interactive Desktop.

Secure Desktop is the default option, and that means that you will not have the ability to interact with other applications until you allow or deny the elevation request. Interactive Desktop means that you have the ability to interact with other application while you are asked for the elevation.

Virtualizes file and registry write failures to per-user locations

This policy defines whether to use File and Registry Virtualization or not. File and Registry Virtualization means that application that are not running in administrator mode will redirected to a specific location if they try to write or read from/to a specific locations like the Program Files and Windows directories for the File Virtualization, and HKLM for the Registry Virtualization.

This policy is enabled by default.

Read about File and Registry Virtualization and see them in action.

Last word

For security reasons, it is recommended that you leave the UAC enabled and leave its default options. But, you must be very wise if you are going to change UAC options -or other security policies of course.-

Windows Vista File and Registry Virtualization

Enabling UAC (User Access Control) feature in Windows Vista, Administrator users in Windows Vista, by default, don’t have administrative privileges. Every Windows process has two security tokens associated with it, one with normal user privileges and one with admin privileges. With applications that require administrative privileges, the user can elevate the application to run with Administrator rights. And that process called Elevation.

As you expect, it’s the least-privilege principle well-recognized for security pros and people who use Linux.

User can elevate an application either by clicking “Run as Administrator” from the context menu of the application icon, or even by editing the Compatibility tab in the properties of the application file.
Also, while an application running it can ask the user to provide administrative permission to complete a specific operation (a good example is switching to the All Users mode in Task Manager).

Compatibility Options

Windows Vista keeps track of the compatibility options edited for an application by adding a compatibility flag to the registry at HKCUSoftwareMicrosoftWindows NTCurrentVersionAppCompatFlagsLayers.

Try changing any of the compatibility options for an application and see how Windows tracks that.

Because UAC feature of Windows Vista, it doesn’t allow users to access some folders like Program Files and Windows folder. Also it doesn’t allow them to access the registry without administrative permission.

But, there’re lots of applications that write lots of data to the Program Files folder for instance. And Windows Vista must keep them away from doing such these operations without administrative permission -you can imagine the amount of applications that require administrative privileges-. So to handle this dilemma, Windows Vista has a new technique called Virtualization.

When a program tries to write to the Program Files folder for instance, Windows Vista redirects it to a special virtual store so that the application can read/write data without generating errors (because of course it doesn’t have the permission).

As we would see in the next example Windows Vista uses this technique with registry too.

For folders, Virtualization called File Virtualization. For registry, it’s called Registry Virtualization.

File Virtualization

To see virtualization in action let’s try this example:

string programFiles =
    Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
string appDir = Path.Combine(programFiles, "MyApplication");

if (Directory.Exists(appDir) == false)
    Directory.CreateDirectory(appDir);

string file = Path.Combine(appDir, "SampleFile.txt");

File.WriteAllText(file, "Hello, World!");

When you run the example it doesn’t write to C:Program FilesMyApplication. Instead it writes to the Program Files virtual store in C:UsersAppDataLocalVirtualStoreProgram FilesMyApplication

Note that if you are running your Visual Studio instance in elevated mode and run your application it gets the elevated mode from Visual Studio. So you need to run it manually from its icon.

Try changing the application so it writes to Windows folder. And check the virtual store folder.

Registry Virtualization

Virtualization is not only done with folders but also with registry entries. If the application tries to write to the registry key Software in HKEY_LOCAL_MACHINE hive, it is redirected to the HKEY_CURRENT_USER hive. Instead of writing to HKLMSoftware{Manufacturer}, it writes to the registry Virtual Store HKCUSoftwareClassesVirtualStoreMACHINESOFTWARE{Manufacturer}.

File and registry virtualization is available only for 32-bit applications. This feature is not available for 64-bit applications on Windows Vista.

Don’t use virtualization as a feature of your application. It is better to fix your application than to write to Program Files folder and the HKLM hive without elevated user privileges. Redirection is only a temporary means to fix broken applications.

Creating Transacted Files

Lastly but not last, and after a long while, Windows Vista introduced a way to create transacted files or even to write to registry.

While market grows remarkably in the last years, its requirements increase as well. And every day you face a new problem that you must overcome to accommodate market requirements.

Transacted operations are one of the commonly demanded requirements by market.

While it’s true that you can easily do database operations transactionally, it’s not enough. Sometimes you will need to write files or make changes to registry in a transactional way.

With previous versions of Windows, you weren’t able to create a file transactionally without writing a huge amount of disorganized code to create it manually. You couldn’t use normal transactions or even COM+ Enterprise Services to create this type of transactions.

With Windows Vista you can easily create transacted files the common way you used to create normal files.

Unfortunately, from .NET 3.5 you cannot create transacted files. So you need to dive into API to create it.

Not Windows Vista only that supports this type of transactions, Windows Server 2008 also supports it.

Creating a transacted file function

To create a transacted file you can use the Kernel23.dll new function CreateFileTransacted.

This function takes the same arguments as the normal CreateFile function plus three more arguments that we are interested of the first one of them, the transaction handle that will be used while creating the file and writing to it.

The definition of this function in C is as follows:

HANDLE CreateFileTransacted(
    LPCTSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile,
    HANDLE hTransaction,
    PUSHORT pusMiniVersion,
    PVOID pExtendedParameter);

We are interested in 6 parameters of these 9.

  • lpFileName:
    The path of the file being created.
  • dwDesiredAccess:
    Defines how file will be accessed. Read only (0x80000000), right only (0x40000000), or both read and write (0xC0000000).
  • dwShareMode:
    Defines the sharing mode -during the operation- for the file. Enabling reading file contents (0x1), writing to it (0x2), reading and writing (0x3), or deleting the file (0x4).
  • dwCreationDisposition:
    Action to take if file exist or do not exist. This argument can take one of the values:
    0x1: Create the file and throw an error if it exists.
    0x2: Always create the file even if it exists.
    0x3: Open the file and throw an error if it doesn’t exist.
    0x4: Open the file or create it if it doesn’t exist.
    0x5: Open the file and clear its contents. Or throw an error if it doesn’t exist.
  • dwFlagsAndAttributes:
    Any additional options. This can be a combination of file attributes like Archive, Hidden, and Encrypted. Also it supports combining options like deleting the file after closing it.
  • hTransaction:
    A handle to our created transaction that we wish to use it in this operation. To get the handle you may take a step further into COM.

Also there’re three arguments that we are not interested on, so you can safely pass it a NULL value:

  • lpSecurityAttributes:
    A SECURITY_ATTRIBUTES object contains an optional security descriptor information for the file.
  • hTemplateFile:
    A handle to a file to read it’s attributes and options to fill the arguments automatically.
  • pusMiniVersion:
    The miniversion to be opened. When creating transacted file -by specifying the hTransaction argument, this must be NULL.
  • pExtendedParameter:
    Reserved.

For a complete discussion of this API function, see MSDN Library.

PInvoking CreateFileTransacted API function

PInvoke is a service that enables you to call unmanaged functions in DLLs, such as those in the Win32 API like the CreateFileTransacted API function last mentioned.

PInvoke stands for Platform Invokation.

In order to PInvoke a function you need to know some things:

  1. Where this function resides (which DLL).
  2. Function definition and order of arguments -if found.-
  3. How to marshal between unmanaged types in .NET types.

Marshaling in .NET is the process of creating a bridge between new .NET types and legacy COM types. This is done by finding equivalents for those legacy types in the new data types or creating it if needed.

Most of the COM data types have equivalents in .NET, also it’s very easy to create your own.

For the function on hands we could write it in C# as following:

[DllImport("kernel32.dll")]
    public static extern
    IntPtr CreateFileTransacted(
    string lpFileName,
    uint dwDesiredAccess,
    uint dwShareMode,
    IntPtr lpSecurityAttributes,
    uint dwCreationDisposition,
    uint dwFlagsAndAttributes,
    IntPtr hTemplateFile,
    IntPtr hHandle,
    IntPtr pusMiniVersion,
    IntPtr pExtendedParameter);

Code explanation:
static extern modifiers are required for creating PInvoke functions.
DllImport attribute used to define the DLL that contains the function.
System.IntPtr is the managed type equivalent to unmanaged HANDLE.
LPCSTR can be easily replaced by the managed System.String.
In unmanaged code DWORD is a 32-bit unsigned integer, so we could safely replace it with System.UInt32.

Because we need to pass a NULL value to the LPSECURITY_ATTRIBUTES argument we marshaled it as IntPtr, so we can use IntPtr.Zero to pass NULL values.
We did that too with the last two arguments.

For creating the PInvoke methods easily, you could use the Red Gate’s PInvoke.NET Visual Studio add-in.
Also you should visit the interop wiki.

After we create our PInvoke method we can call it. But after that we need to create the transaction and get its handle to fill the arguments of the method.

To get a transaction handle we need to dive into COM and call a method to get the handle. This method is wrapped to .NET using COM Interop.

[ComImport]
[Guid("79427A2B-F895-40e0-BE79-B57DC82ED231")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IKernelTransaction
{ void GetHandle(out IntPtr ktmHandle); }

Don’t forget adding a using System.Runtime.InteropServices statement.

Now we can call the method:

private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
private const uint GENERIC_WRITE = 0x40000000;
private const uint CREATE_ALWAYS = 0x2;
private const uint FILE_SHARE_NONE = 0x0;

static void Main()
{
    using (TransactionScope scope = new TransactionScope())
    using (FileStream stream = CreateTransactedFile("D:SampleFile.txt"))
    using (StreamWriter writer = new StreamWriter(stream))
    {
        writer.WriteLine("Hello, World!");

        // To commit the transaction use the followind line
        scope.Complete();
    }
}

public static FileStream CreateTransactedFile(string fileName)
{
    IKernelTransaction ktx = (IKernelTransaction)
        TransactionInterop.GetDtcTransaction(Transaction.Current);

    IntPtr txHandle;
    ktx.GetHandle(out txHandle);

    IntPtr fileHandle =
        CreateFileTransacted(fileName,
        GENERIC_WRITE, FILE_SHARE_NONE, IntPtr.Zero,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
        IntPtr.Zero, txHandle, IntPtr.Zero, IntPtr.Zero);

    return new FileStream(fileHandle, FileAccess.Write);
}

Don’t forget adding a reference to System.Transactions and a using statement.

Code explanation:
Constants define the input for the function arguments.
In method CreateTransactedFile() we get the handle of the ambient transaction created in method Main(). Then we call the CreateFileTransacted() function which returns a pointer to the create file. Lastly we created the FileStream object with the created the file handle and used it to create a StreamWriter object to write textual data to the file.

Calling Commit() of the transaction object ensures that all operations completed successfully and now we can apply it. Otherwise, nothing would be done. That’s the main characteristic of transactions. All or nothing.

You don’t need to close the transaction handle manually because when disposing the TransactionScope object it will close its handle automatically.
If you are interested in closing it manually you can use the .NET wrapper System.Runtime.InteropServices.Marshal.Release() method. Or try the difficult way using the CloseHandle unmanaged handle.

Transactional support not limited to creating a file only. Most file system operation now support transactions, some examples are CopyFileTransacted, CreateDirectoryTransacted, CreateHardLinkTransacted, DeleteFileTransacted, MoveFileTransacted, RemoveDirectoryTransacted, and SetFileAttributesTransacted.

The complete example can be downloaded here.