Archive

Archive for February, 2012

Registry Redirector (Windows)

February 28, 2012 Leave a comment

The registry redirector isolates 32-bit and 64-bit applications by providing separate logical views of certain portions of the registry on WOW64. The registry redirector intercepts 32-bit and 64-bit registry calls to their respective logical registry views and maps them to the corresponding physical registry location. The redirection process is transparent to the application. Therefore, a 32-bit application can access registry data as if it were running on 32-bit Windows even if the data is stored in a different location on 64-bit Windows.

A subset of keys under redirected registry paths are shared. 32-bit registry calls to shared keys are not redirected. Instead, one physical copy of the key is mapped into each logical view of the registry. For a list of redirected keys and shared keys, see Registry Keys Affected by WOW64.

Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: To enable application interoperability through COM and other mechanisms, a subset of redirected registry keys are also reflected. The process of registry reflection copies registry keys and values between two registry views to keep them synchronized. Registry reflection was removed starting with Windows 7 and Windows Server 2008 R2. For more information, see Registry Reflection.

The following scenario illustrates the use of these logical views:

  • A 32-bit application checks for the existence of the following registry key: HKEY_LOCAL_MACHINE\Software\Hello. If the key does not exist, the application creates it with a default value of "Hello 32-bit world"; otherwise, it reads and displays the value.
  • The same application is modified to write "Hello 64-bit world" instead of "Hello 32-bit world" and recompiled as a 64-bit application.
  • When the 32-bit application is run on 64-bit Windows, it displays "Hello 32-bit world". When the 64-bit application is run, it displays "Hello 64-bit world". Both applications call the same registry functions with the same predefined handle and the same key name; the difference is that each application operates on its logical view of registry, and each view is mapped to a separate physical location of the registry, which keeps both versions of the string intact.

Redirected keys are mapped to physical locations under Wow6432Node. For example, HKEY_LOCAL_MACHINE\Software is redirected to HKEY_LOCAL_MACHINE\Software\Wow6432Node. However, the physical location of redirected keys should be considered reserved by the system. Applications should not access a key’s physical location directly, because this location may change. For more information, see Accessing an Alternate Registry View.

To help 32-bit applications that write REG_SZ or REG_EXPAND_SZ data containing %ProgramFiles% or %commonprogramfiles% to the registry, WOW64 intercepts these write operations and replaces them with "%ProgramFiles(x86)%" and "%commonprogramfiles(x86)%". For example, if the Program Files directory is on the C drive, then "%ProgramFiles(x86)%" expands to "C:\Program Files (x86)". The replacement occurs only if the following conditions are met:

  • The string must begin with %ProgramFiles% or %commonprogramfiles%. If the string begins with a space or any character other than %, it is not replaced.
  • The case of %ProgramFiles% or %commonprogramfiles% must be exactly as shown because the string comparison is case-sensitive. For example, if the string begins with %CommonProgramFiles% instead of %commonprogramfiles%, it is not replaced.
  • The string cannot exceed MAX_PATH*2+15 characters. If it exceeds this length, it is not replaced.
  • The key cannot be opened with KEY_WOW64_64KEY. This flag specifies that operations on the key should be performed on the 64-bit registry view, so it is not replaced. For more information, see Accessing an Alternate Registry View.

Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: The KEY_WOW_64_64KEY flag does not affect whether a key is replaced. This flag affects replacement starting with Windows 7 and Windows Server 2008 R2.

In addition, REG_SZ or REG_EXPAND_SZ keys containing system32 are replaced with syswow64. The string must begin with the path pointing to or under %windir%\system32. The string comparison is not case-sensitive. Environment variables are expanded before matching the path, so all of the following paths are replaced: %windir%\system32, %SystemRoot%\system32, and C:\windows\system32.

For more information, see the following topics:

Source: Registry Redirector (Windows)

Categories: Repackaging

Registry Virtualization

February 28, 2012 Leave a comment

Registry virtualization is an application compatibility technology that enables registry write operations that have global impact to be redirected to per-user locations. This redirection is transparent to applications reading from or writing to the registry. It is supported starting with Windows Vista.

This form of virtualization is an interim application compatibility technology; Microsoft intends to remove it from future versions of the Windows operating system as more applications are made compatible with Windows Vista and later versions of Windows. Therefore, it is important that your application does not become dependent on the behavior of registry virtualization in the system.

Virtualization is intended only to provide compatibility for existing applications. Applications designed for Windows Vista and later versions of Windows should not write to sensitive system areas, nor should they rely on virtualization to remedy any problems. When updating existing code to run on Windows Vista and later versions of Windows, developers should ensure that applications only store data in per-user locations or in computer locations within %alluserprofile% that properly use an access control list (ACL).

For more information about building UAC-compliant applications, see the UAC Developer Guide.

Virtualization Overview

Prior to Windows Vista, applications were typically run by administrators. As a result, applications could freely access system files and registry keys. If these applications were run by a standard user, they would fail due to insufficient access rights. Windows Vista and later versions of Windows improve application compatibility for these applications by automatically redirecting these operations. For example, registry operations to the global store (HKEY_LOCAL_MACHINE\Software) are redirected to a per-user location within the user’s profile known as the virtual store (HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software).

Registry virtualization can be broadly classified into the following types:

Open Registry Virtualization

If the caller does not have write access to a key and attempts to open the key, the key is opened with the maximum allowed access for that caller.

If the REG_KEY_DONT_SILENT_FAIL flag is set for the key, the operation fails and the key is not opened. For more information, see "Controlling Registry Virtualization" later in this topic.

Write Registry Virtualization

If the caller does not have write access to a key and attempts to write a value to it or create a subkey, the value is written to the virtual store.

For example, if a limited user attempts to write a value to the following key: HKEY_LOCAL_MACHINE\Software\AppKey1, virtualization redirects the write operation to HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\AppKey1.

Read Registry Virtualization

If the caller reads from a key that is virtualized, the registry presents a merged view of both the virtualized values (from the virtual store) and the non-virtual values (from the global store) to the caller.

For example, suppose HKEY_LOCAL_MACHINE\Software\AppKey1 contains two values V1 and V2 and that a limited user writes a value V3 to the key. When the user attempts to read values from this key, the merged view includes values V1 and V2 from the global store and value V3 from the virtual store.

Note that virtual values take precedence over global values when present. In the example above, even if the global store had value V3 under this key, the value V3 would still be returned to the caller from the virtual store. If V3 were to be deleted from the virtual store, then V3 would be returned from the global store. In other words, if V3 were to be deleted from HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\AppKey1 but HKEY_LOCAL_MACHINE\Software\AppKey1 had a value V3, then that value would be returned from the global store.

Registry Virtualization Scope

Registry virtualization is enabled only for the following:

  • 32-bit interactive processes.
  • Keys in HKEY_LOCAL_MACHINE\Software.
  • Keys that an administrator can write to. (If an administrator cannot write to a key, then the application would have failed on previous versions of Windows even if it was run by an administrator.)

Registry virtualization is disabled for the following:

  • 64-bit processes.
  • Processes that are not interactive, such as services.

    Note that using the registry as an inter-process communication (IPC) mechanism between a service (or any other process that does not have virtualization enabled) and an application will not work correctly if the key is virtualized. For instance, if an antivirus service updates its signature files based on a value set by an application, the service will never update its signature files because the service reads from the global store but the application writes to the virtual store.

  • Processes that impersonate a user. If a process attempts an operation while impersonating a user, that operation will not be virtualized.
  • Kernel-mode processes such as drivers.
  • Processes that have requestedExecutionLevel specified in their manifests.
  • Keys and subkeys of HKEY_LOCAL_MACHINE\Software\Classes, HKEY_LOCAL_MACHINE\Software\Microsoft\Windows, and HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT.
Controlling Registry Virtualization

In addition to controlling virtualization at an application level by using requestedExecutionLevel in the manifest, an administrator can enable or disable virtualization on a per-key basis for keys in HKEY_LOCAL_MACHINE\Software. To do this, use the Reg.exe command-line utility FLAGS option with the flags listed in the following table.

Flag
Meaning

REG_KEY_DONT_SILENT_FAIL
This flag disables open registry virtualization. If this flag is set and an open operation fails on a key that has virtualization enabled, the registry does not attempt to reopen the key. If this flag is clear, the registry attempts to reopen the key with MAXIMUM_ALLOWED access instead of the requested access.

REG_KEY_DONT_VIRTUALIZE
This flag disables write registry virtualization. If this flag is set and a create key or set value operation fails because the caller does not have sufficient access right to the parent key, the registry fails the operation. If this flag is clear, the registry attempts to write the key or value in the virtual store. The caller must have the KEY_READ right on the parent key.

REG_KEY_RECURSE_FLAG
If this flag is set, registry virtualization flags are propagated from the parent key. If this flag is clear, registry virtualization flags are not propagated. Changing this flag affects only new descendent keys created after the flag is changed. It does not set or clear these flags for existing descendent keys.

The following example shows the use of the Reg.exe command-line utility with the FLAGS option to query the state of the virtualization flags for a key.

Copy

C:\>reg flags HKLM\Software\AppKey1 QUERY

HKEY_LOCAL_MACHINE\Software\AppKey1

        REG_KEY_DONT_VIRTUALIZE: CLEAR
        REG_KEY_DONT_SILENT_FAIL: CLEAR
        REG_KEY_RECURSE_FLAG: CLEAR

The operation completed successfully.

Whenever auditing is enabled on a key that is being virtualized, a new virtualization audit event is generated to indicate that the key is being virtualized (addition to the usual audit events). Administrators can use this information to monitor the status of virtualization on their systems.

Related topics
Getting Started with User Account Control
Understanding and Configuring User Account Control
Developer Best Practices and Guidelines for Applications in a Least Privileged Environment

 

Source: Registry Virtualization

Categories: Programming, Repackaging

Use ShellExecute to launch the default Web browser

February 28, 2012 Leave a comment

SUMMARY

This article provides general information about how to register the default Web…

This article provides general information about how to register the default Web browser and then how to start the default Web browser with the ShellExecute application programming interface (API). It also provides details on how ShellExecute causes Microsoft Internet Explorer to go to a Uniform Resource Locator (URL).

Back to the top

MORE INFORMATION

Determine the Default Web Browser By default, Microsoft Internet Explorer checks…

Determine the Default Web Browser

By default, Microsoft Internet Explorer checks to see if it is the default Web browser each time that it starts. If Internet document (HTML) files are associated with a different browser when Internet Explorer starts, Internet Explorer recognizes that it is not the default browser and then prompts you to make it the default browser.
When you select Make this the default browser in Internet Explorer and in later versions of Netscape, the browser registers itself into all of the following keys to make itself the default browser (among other entries that are written). HKEY_CLASSES_ROOT\.htm HKEY_CLASSES_ROOT\.html HKEY_CLASSES_ROOT\http\shell\open\command HKEY_CLASSES_ROOT\http\shell\open\ddeexec\Application HKEY_CLASSES_ROOT\ftp\shell\open\command HKEY_CLASSES_ROOT\ftp\shell\open\ddeexec\Application HKEY_CLASSES_ROOT\gopher\shell\open\command HKEY_CLASSES_ROOT\gopher\shell\open\ddeexec\Application

Back to the top

Start the Default Web Browser from Your Application

Call the ShellExecute API and pass it a URL. That is the easiest way for you to start the default Web browser from your application. If the default Web browser currently runs, ShellExecute tells the instance that runs to go to your Uniform Resource Locator (URL). If it is not running, ShellExecute starts the application and then browses to your URL.
If you used Microsoft Visual C++ to develop your application, the following code describes how to call ShellExecute.

LONG r = ShellExecute(NULL, "open", "http://www.microsoft.com", NULL, NULL, SW_SHOWNORMAL);
				

If you used Microsoft Visual Basic, you must insert the ShellExecute declaration in your project. You can find this declaration in the Win32api.txt file that is located in a sub-folder of your Microsoft Visual Studio installation. Optionally, you may copy it from the API Text Viewer tool that comes with Visual Studio 6.0.

To insert the ShellExecute API into your project, follow these steps:

  1. Create a new project in Visual Basic.
  2. Select Standard EXE.
  3. Add a button to your form.
  4. Put the following code in the form.

    Private Declare Function ShellExecute _
                                Lib "shell32.dll" _
                                Alias "ShellExecuteA"( _
                                ByVal hwnd As Long, _
                                ByVal lpOperation As String, _
                                ByVal lpFile As String, _
                                ByVal lpParameters As String, _
                                ByVal lpDirectory As String, _
                                ByVal nShowCmd As Long) _
                                As Long
    
    Private Sub Command1_Click()
       Dim r As Long
       r = ShellExecute(0, "open", "http://www.microsoft.com", 0, 0, 1)
    End Sub
    						

  5. Run your project, and then click the button to go to your URL with the default Web browser.

The ShellExecute API is supported on Microsoft Windows 95 and Microsoft Windows NT 3.1 and later. You can use ShellExecute to activate the default Web browser in all Win32 versions of Microsoft Internet Explorer from version 1.0 and later. This technique is not supported on the Microsoft Windows 3.x, UNIX, or on MacIntosh platforms.

Back to the top

How ShellExecute Works

The following background is for informational purposes only. It is provided so that you can better understand how your application interacts with the operating system. Do not base your designs on assumptions that you draw from this information. Be aware that this functionality may change in future versions of Microsoft products.

How ShellExecute Interprets the URL Passed

ShellExecute parses the string that is passed to it so that ShellExecute can extract either a protocol specifier or an extension. Next, ShellExecute looks in the registry and then uses either the protocol specifier or the extension to determine which application to start. If you pass http://www.microsoft.com to ShellExecute, ShellExecute recognizes the http:// sub-string as a protocol, which causes ShellExecute to view

HKEY_CLASSES_ROOT\http\shell\open

for information about how to run. If you pass myfile.htm to ShellExecute, ShellExecute recognizes the ".htm" sub-string as an extension. This causes ShellExecute to view

HKEY_CLASSES_ROOT\.htm

, which leads to

HKEY_CLASSES_ROOT\htmlfile\shell\open

.

Typically, it is best to fully specify your URL in the string that is passed to ShellExecute, for example: http://www.microsoft.com instead of www.microsoft.com. When you fully specify the URL, you make sure that ShellExecute knows exactly which protocol you want. By default, however, ShellExecute detects some patterns that include www.* and ftp.*, and then maps those patterns to the Hypertext Transfer Protocol (HTTP) protocol and the File Transfer Protocol (FTP), respectively.

How ShellExecute Determines Whether to Start a New Instance

When ShellExecute looks through the registry, it looks for the

shell\open

subkey. If the

shell\open\ddeexec

key is defined, then a Dynamic Data Exchange (DDE) message with the specified application IExplore and the topic WWW_OpenURL is broadcast to all top-level windows on the desktop. The first application to respond to this message is the application that goes to the requested URL. If no application responds to this DDE message, then ShellExecute uses the information that is contained in the

shell\open\command

subkey to start the application. It then re-broadcasts the DDE message to go to the requested URL.

Back to the top

REFERENCES

For more information about default Web browsers, click the following article num…

For more information about default Web browsers, click the following article number to view the article in the Microsoft Knowledge Base:

153774 (http://support.microsoft.com/kb/153774/ ) Internet Explorer not configured as default browser

The third-party products that this article discusses are manufactured by companies that are independent of Microsoft. Microsoft makes no warranty, implied or otherwise, about the performance or reliability of these products.

Back to the top


APPLIES TO
  • Microsoft Windows 2000 Server
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Internet Explorer 3.01
  • Microsoft Internet Explorer 3.02
  • Microsoft Internet Explorer 4.0 128-Bit Edition
  • Microsoft Internet Explorer 4.01 Service Pack 2
  • Microsoft Internet Explorer 4.01 Service Pack 1
  • Microsoft Internet Explorer 4.01 Service Pack 2
  • Microsoft Internet Explorer 5.0
  • Microsoft Internet Explorer 5.01
  • Microsoft Internet Explorer (Programming) 5.01 SP1
  • Microsoft Internet Explorer 5.5
  • Microsoft Internet Explorer (Programming) 5.5 SP1
  • Microsoft Internet Explorer (Programming) 5.5 SP2
  • Microsoft Internet Explorer (Programming) 6 (SP1)
  • Microsoft Windows NT Server 3.5
  • Microsoft Windows NT Server 3.51
  • Microsoft Windows NT Server 4.0 Standard Edition
  • Microsoft Windows NT Workstation 3.5
  • Microsoft Windows NT Workstation 3.51
  • Microsoft Windows NT Workstation 4.0 Developer Edition

Source: Use ShellExecute to launch the default Web browser

Categories: Programming

AppShadow: Side-by-side components the other way

February 28, 2012 Leave a comment

Side-by-side components the other way

Important This article contains information about modifying the registry. Before you modify the registry, make sure to back it up and make sure that you understand how to restore the registry if a problem occurs. For information about how to back up, restore, and edit the registry, click the following article number to view the article in the Microsoft Knowledge Base:
256986 Description of the Microsoft Windows Registry

Abstract

Ever wanted to run some legacy Access 97 application side by side with the latest Microsoft Office suite? Or ever wondered why you cannot install different versions of some applications at the same time on your machine? Then the following will be interesting for you, because in this article I will present a method on how to virtualize the Windows registry on an application (process) basis. You can do it with AppShadow.
By this means you could host multiple versions of otherwise mutual exclusive applications or components on the same machine at the same time. Moreover you can circumvent shortcomings in applications that are normally not meant to be run in a Terminal Server environment.
In order to get the most out of this article some know-how about

  • Windows Terminal Server
  • Windows DLLs
  • Windows API programming

is absolutely recommended. If you do not like changing system settings or are not sure what you are doing please stop reading and do not waste your time reading this article.

Background

When running in a Terminal Server environment, every user receives its own copy of user specific registry settings (where one normally has full access, KEY_ALL_ACCESS). These settings reside in a hive called HKEY_CURRENT_USER (HKCU for short, physically stored in "%USERPROFiLE%\ntuser.dat"). To ease the propagation of changes Windows implements a mechanism called "Shadowing" (from which I borrowed the name AppShadow). The shadow registry is a special registry tree that can be seen as a layer on top of the user’s settings. Each entry in the shadow area corresponds to an entry in HKCU:

Picture: Mapping between shadow area and HKCU
Click to show picture

Every time a user requests a key or value from its HKCU, Windows looks into the "shadow registry" or "shadow area" first if there is a (newer) entry. If available, this entry will be copied to the user’s location – eventually overwriting existing older entries. To determine if entries in the shadow area are newer than those already present in HKCU Windows compares the last write time (a FILETIME structure) of both keys. For some information about editing the access time on registry keys see RegTimeStamp. The shadow area is currently defined at the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install

Machine wide settings are kept in a different area, HKEY_LOCAL_MACHINE (HKLM). Applications can define settings that are global for all users. Normally, only privileged users such as "Administrators" can change entries in this hive. Other users such as "Authenticated Users" have only read permissions, KEY_READ, on these keys. Within HKLM under the key called SOFTWARE (physically stored in "%SYSTEMROOT%\system32\config\software") there is a subkey called Classes that can be referred to as HKEY_CLASSES_ROOT (HKCR).

Picture: Mapping between HKLM\SOFTWARE\Classes and HKCR
Click to show picture

In this area, system-wide registrations of components are kept (CLSIDs, ProgIds, TypeLibs and Interfaces) and among others, file associations for all users. As HKCR is a global instance it means that once, for example, a file association is defined in this place, every user on that machine has the same program that handles this association.

Beginning with Windows 2000 the operating systems tries to ease the implications of one single HKCR branch and introduces user specific software registration. From now on, every user has a private Classes key that maps transparently over HKCR, referred to as HKEY_USER_CLASSES (HKUC).

Picture: Mapping between HKCU\SOFTWARE\Classes and HKUC
Click to show picture

These settings are saved in a file called UsrClass.dat. The file resides in a non-roaming area of your profile: CSIDL_LOCALAPPDATA. So all changes you make are lost after you log off. Everytime a registry call to HKCR is made, the system tries to look in HKUC first. The calling application is normally unaware of this behaviour. By utilizing this feature, every user can have his different file association for documents, for example. Entries in HKUC alyways have precedence over entries in HKCR. But these settings affect all applications throughout the session. Competing applications that defines values in the same area may produce unpredictable results or simply complain that the application is not installed properly.

Though applications can seamlessly read from HKUC when actually opening keys in HKCR, they may still fail when trying to write or register components in HKCR as of insufficient (write) permissions. These requests are not remapped to HKUC! This is a major annoyance as many developers (or maybe just syntactical coders?) still open resources with KEY_ALL_ACCESS permissions while really only read access is allthey really want. (You can use Regmon from Sysinternals to see how applications open registry keys.

If you would like to know more about the registry in a Terminal Server environment, please have a look at Brian Madden’s web site:

Or have a look at these documents

Registry virtualization

If every process had its private copy of required registry keys and values along with all the permissions it needed to open these resources, world peace would come probably closer – at least for the average administrator or system integrator…
So what we are trying to do is the following: We build a special area of registry keys just like the "shadow area". Every time our application looks up some values, we look in that area first and see if there are values that could be returned to the application. This can be done by redirecting the registry interface of Windows:
From a Win32 programmers perspective, all registry access is implemented via the ADVAPI32 interface. ADVAPI32.DLL is a well known system DLL that is mapped into your program if it makes calls to security and registry functions. In order to virtualize the registry for arbitrary processes, we must somehow replace or redirect calls to the original ADVAPI32.DLL to our library that can redirect calls to our shadow area. So we would supply a DLL with the same name that has the same exports as the original DLL and place it into the programs directory so that our library is called before the original DLL. Unfortunately, Windows treats ADVAPI32 as a special "well known" library and thus prefers loading the real library instead of ours.

DLL redirection to the rescue!

Windows 2003 Luckily there is a feature known as "DLL redirection" within Windows 2003 that instructs the Windows Loader to search libraries in the application directory first. Just as we want it! This works by adding a special folder called APPNAME.EXE.LOCAL into the program directory and copying our library into that folder (if we wanted to redirect Winword we would replace APPNAME.EXE.LOCAL with WINDORD.EXE.LOCAL).

Picture: DLL redirection with Windows 2003
Click to show picture

By doing this our library is called before the original library and has a chance to get loaded.

Note For more information about the load mechanism in Windows, I recommend to read Matt Pietrek‘s articles about PE images (in the MSJ series "Under the Hood") or to have a look at What Goes On Inside Windows 2000: Solving the Mysteries of the Loader.

Windows 2000 Windows 2000 only supports a redirection file (for Winword it would be "WINWORD.EXE.LOCAL"). In that case, the library has to be put into the application directory – possibly affecting other applications as well.

Picture: DLL redirection with Windows 2000
Click to show picture

Apart from that, we have to tell Windows 2000 to treat ADVAPI32 as an ordinary library excluding it from KnownDLLs. So we use RegEdt32.Exe to add a value to the following entry: "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\ExcludeFromKnownDlls" (REG_MULTI_SZ). You have to reboot until changes take effect.

Picture: ExcludeFromKnownDlls
Click to show picture

The export table

Finally being loaded as ADVAPI32, the only thing left is to check every registry access (function call) and to see if it should get a special "treatment". If we want to redirect the registry access to somewhere else, we do it – otherwise we just leave the call as it is and do what the real library would have done anyway. For this to happen, our library has to export the same function names as the original DLL (as I mentioned earlier). By using DumpBin.Exe with the /EXPORTS switch from the Platform SDK, for example, we can build our own export table.
Warning But be careful: Between different operating systems, the export table changes (specificially the ordinals)! That’s why we need a different version for every operating system we support (Windows 2000, Windows XP, Windows 2003).

NTFS hardlinks come in handy

After having made up what to do, we finally would like to call the original ADVAPI32.DLL from the system’s directory to redirect the registry call made by the application. But there is a problem: We told Windows we wanted a DLL redirection. So when we try to load the original library from the system directory, Windows first tries to load the library from the application directory. As this is our library, we end up in loop loading us again and again until the stack is exhausted and the loader terminates the application. What an unpleasant surprise!

Though one possible solution would be to make a copy of the original DLL and name it to something else. But every time a new update is installed on the system that copy would have to be updated as well (and you know – there are a lot of latest and greatest fixes around these days)…
This is the place where we use an NTFS hardlink, a concept that UNIX knows for a long time: a hardlink is like an alias or pointer to a different file. Every time you open the hardlink, the system opens the real file instead.
Instead of loading ADVAPI32.DLL we load our NTFS hardlink ADVAPI32.DF that we created in "%SYSTEMROOT%\system32". By doing this, we avoid the naming collision and also have only a single copy of the original DLL on the system!
Note As a trade off, the program runs only on NTFS partitions but that should be no real restriction.

Implementation details

Like the shadow area from Windows we need a place where to store the virtual HKLM and HKCU settings for the applications that we want to redirect. The main place where everything starts is:

HKEY_LOCAL_MACHINE\SOFTWARE\d-fens\AppShadow

For every program you want redirection to occur, you define a mapping as seen in the picture. In this example, we define a mapping for Microsoft Access 97 Runtime (MSACCESS.EXE, full path "C:/DATEV/PROGRAMM/QSELZK97/Office/MSACCESS.EXE").

Note All "\" characters have to be replaced with "/" characters!

Within the key is a REG_SZ "Index" pointing to the location where all shadow registry settings should be kept. In this case, it points to the "Access97Runtime" key below "Registry" (see the red arrow). There you have to define 2 keys: "HKLM", and "HKCU". These keys will be the application’s new HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER keys. HKCR and HKUC are consequently defined at "SOFTWARE\Classes" in their respective branches. If no keys are defined, no redirection occurs.

Note You always have to define both entries (HKLM, HKCR and HKCU, HKUC) together to activate redirection. If you omit HKCR (that is the SOFTWARE\Classes branch below our virtual HKLM), for example, HKLM\SOFTWARE\Classes and HKCR would point to different places and unpredictable results could occur. Thanks to Thomas Lehrer for clarifications on this one.

Picture: Redirected HKLM

Click to show picture

Picture: Redirected HKCU

Click to show picture

HKCU remapping

If you want to remap HKCU entries as well, AppShadow will copy all entries below "HKEY_LOCAL_MACHINE\SOFTWARE\d-fens\AppShadow\Registry\Saperion-DMS\HKCU" to "HKEY_CURRENT_USER\Software\d-fens\AppShadow\Registry\Saperion-DMS\HKCU" on application startup , because the user must have write access to these keys.

Role based redirection

Picture: Role based redirection

Click to show picture

When defining access permissions on the Appname registry key, you can control for which users redirection should be active. In the shown example, you can see that only "Saperion-DMSUsers" should get a redirection of registry keys.

Per user HKLM redirection

If redirecting HKLM per process is still not enough for you might consider using the "private HKLM" feature. This is useful if application store user specific settings in HKLM (like Netscape 4 or Cashier4Windows) and you want them to separate. To enable this feature you must create the following registry key (in the same path where you create the "Index" REG_SZ):

PerUserHKLM	REG_DOWRD	0x00000001

Upon start AppShadow checks if HKLM is not already defined in "HKEY_CURRENT_USER\SOFTWARE\d-fens\AppShadow\Registry\’IndexName’" and then copies all keys from "HKEY_LOCAL_MACHINE\SOFTWARE\d-fens\AppShadow\Registry\’IndexName’" to this location with security set to KEY_ALL_ACCESS. If HKLM is already defined in "HKEY_CURRENT_USER\SOFTWARE\d-fens\AppShadow\Registry\’IndexName’" no keys are copied. By this you can deploy a set of individual registry keys per policy to your users.

 
What went wrong?

In case the redirection does not work as expected, AppShadow has built-in logging that you can use to trouble-shoot the error. Every registry call is logged via OutputDebugString(), so all you need is a debug monitor like DebugView from Sysinternals and off you go! This certainly degrades system performance, so make sure you only log when really needed!

Note When trying to log a program from a different Terminal Server session, keep in mind that the kernel objects namespace is separated. Use my OutputDebugString redirector, for example, to redirect the debug stream.

Checklist

Here is a list that you can use for checking in case something does not work as you want it:

  • Setup redirection parameters in "HKLM\SOFTWARE\d-fens\AppShadow"
  • The correct version of ADVAPI32.DLL for the targeted operating system
  • A redirection file APPNAME.EXE.LOCAL when running on Windows 2000
  • ADVAPI32.DLL in the same directory of the program you want to redirect when running on Windows 2000
  • ADVAPI32.dll put in ExcludeFromKnownDlls when running on Windows 2000 (with reboot)
  • A redirection folder APPNAME.EXE.LOCAL when running on Windows 2003 or Windows XP
  • ADVAPI32.DLL in a subfolder APPNAME.EXE.LOCAL of the program you want to redirect when running on Windows 2003 or Windows XP
  • The correct version of ADVAPI32.DLL for the targeted operating system
  • An NTFS hardlink "%SYSTEMROOT%\system32\ADVAPI32.DF" pointing to "%SYSTEMROOT%\system32\ADVAPI32.dll"
  • What is logged via OutputDebugString? Does AppShadow tell you whether DLLs and exports could be loaded?
Which registry settings are needed for redirection?

Tough question. It depends on the application you want to redirect. A good thing could be to use an installation monitor that tracks changes in your registry. Import these settings into the AppShadow entry for your application and test it. Sometimes it will suffice to trace with Regmon to see what the application is doing.

 
Some final words

I believe that the features presented in this article should be made available by the operating system! Microsoft talks a lot about server virtualization and scalability. This would really add a benefit to Microsoft Terminal Services!

I know that some people would hesitate to use tools like AppShadow because of support or stability concerns. I do not say that this program is free of bugs but the whole mechanism is implemented in user mode. There is no reason to fear that this could crash your operating system! But, of course, I cannot take any responsibility if something works not as you expect.

When I came up with the idea for AppShadow my customer faced a problem that questioned the success of the whole project. When I first presented the workaround, he was not too pleased. But as it seemed to be the only viable option we had, he gave it a try. In the near future we discovered that we could "integrate" other misbehaving applications as well on our Terminal Servers that would not have been possible otherwise. Test and see for yourself. And of course, leave me a note if you have questions or suggestions (please mail to AppShadow at d-fens dot net).

 

Source: AppShadow

Categories: Repackaging

Microsoft Windows 2000 Scripting Guide – Sending Keystrokes to a Program

February 28, 2012 Leave a comment

Microsoft® Windows® 2000 Scripting Guide

By providing scripts with access to most COM objects, WSH enables you to automate applications that have a COM-based object model. Unfortunately, some applications, especially older ones, do not have a COM-based object model. To automate these applications, WSH provides a way to send keystrokes to these applications.

When you use the WshShell SendKeys method to send keystrokes to an application, your script mimics a human typing on the keyboard. To send a single keyboard character, you pass SendKeys the character itself as a string argument. For example, "x" to send the letter x. To send a space, send the string " ". This is exactly what a user would do if he or she was working with the application: to type the letter x, the user would simply press the x key on the keyboard.

When you use the SendKeys method, special keys that do not have a direct text representation (for example, CTRL or ALT) are represented by special characters. Table 3.16 lists these SendKeys representations for commonly used keys.

Table 3.16 SendKeys Representations of Common Keys

Key

SendKeys Representation

BACKSPACE

{BACKSPACE}, {BS}, or {BKSP}

BREAK

{BREAK}

CAPS LOCK

{CAPSLOCK}

DEL or DELETE

{DELETE} or {DEL}

DOWN ARROW

{DOWN}

END

{END}

ENTER

{ENTER} or ~

ESC

{ESC}

HELP

{HELP}

HOME

{HOME}

INS or INSERT

{INSERT} or {INS}

LEFT ARROW

{LEFT}

NUM LOCK

{NUMLOCK}

PAGE DOWN

{PGDN}

PAGE UP

{PGUP}

PRINT SCREEN

{PRTSC}

RIGHT ARROW

{RIGHT}

SCROLL LOCK

{SCROLLLOCK}

TAB

{TAB}

UP ARROW

{UP}

SHIFT

+

CONTROL

^

ALT

%

BACKSPACE

{BACKSPACE}, {BS}, or {BKSP}

All function keys, like F1, are represented by the button name contained within braces for example, {F1} for the F1 button and {F2} for the F2 button.

For example, the following script starts Notepad and then types the sentence, "This is a test."

Copy

Set objShell = WScript.CreateObject("WScript.Shell")

objShell.Run "Notepad.exe"

Do Until Success = True

Success = objShell.AppActivate("Notepad")

Wscript.Sleep 1000

Loop

objShell.SendKeys "This is a test."

When the script runs, Notepad will open, and the sample sentence will be typed in, as shown in Figure 3.12.

Figure 3.12 Controlling Notepad by Using SendKeys

clip_image001

Note

  • You can send repeated keystrokes by using the SendKeys method. For example, to send the letter a ten times, you send the string "{a 10}". You must include a space between the keystroke and the number. SendKeys allows you to send only repeated single keystrokes. You cannot send multiple characters using repeated keystrokes; for example, this command will fail: {dog 10}.

You should be aware that sending keystrokes to an application is not the optimal method for automating a procedure. If you have an application in your enterprise that you need to automate and it has no COM-based object model, you might consider this technique. However, you should first examine whether other methods exist for automating that particular application.

Although SendKeys can be used effectively, there are several potential problems with this approach:

  • The script might have difficulty determining which window to send the keystrokes to.
  • Because the application runs in GUI mode, a user might close the application prematurely. Unfortunately, this will not terminate the script, and the script could end up sending keystrokes to the wrong application.
  • The script might have difficulty synchronizing with the application.

This timing issue is especially troublesome, simply because scripts tend to run much faster than GUI applications. For example, this simple script, which starts Calculator and then tries to type the number 2 into the application, is coded correctly but will likely fail when run (Calculator will start, but the number 2 will not be entered):

Copy

Set objShell = WScript.CreateObject("WScript.Shell")

objShell.Run "Calc.exe"

objShell.AppActivate "Calculator"

objShell.SendKeys "2"

The script fails not because of a syntax issue but because of a timing issue. As quickly as it can, the script issues commands to:

  1. Start Calculator.
  2. Switch the focus to Calculator (using the AppActivate method).
  3. Send the number 2 to Calculator.

Unfortunately, the script runs faster than Calculator can load. As a result, the number 2 is sent, and the script terminates, before Calculator can finish loading and start accepting keystrokes.

There are at least two ways of working around this problem. First, you might be able to estimate how long it will take an application to load and then pause the script for that amount of time. For example, in this script the Run method is called, and then the script pauses for 5 seconds, giving Calculator time to load:

Copy

Set objShell = WScript.CreateObject("WScript.Shell")

objShell.Run "Calc.exe"

Wscript.Sleep 5000

objShell.AppActivate "Calculator"

objShell.SendKeys "2"

Of course, is some cases it might be difficult to estimate how long it will take before an application is loaded and ready to accept keystrokes. In that case, you can call the AppActivate method and check the return value.

Using AppActivate

Before sending keystrokes to an application, you must first ensure that the application is running and that the focus is on the application (that is, the application is running in the active window). You can use the AppActivate method to set the focus on an application. The AppActivate method brings the specified window to the foreground so that you can then start using the WshShell SendKeys method to send keystrokes to the application.

The AppActivate method takes a single parameter that can be either a string containing the title of the application as it appears in the title bar or the process ID of the application. The AppActivate method returns a Boolean value that indicates whether the procedure call has been successful. If the value is False, AppActivate has failed, usually because it was unable to find the application (possibly because that application had not finished loading).

You can place your script in a loop, periodically calling AppActivate until the return value is True. At that point, the application is loaded and prepared to accept keystrokes.

For example, this script checks the return value for AppActivate. If this value is False, the script pauses for 1 second and then checks the value again. This continues until the return value is True, meaning that the application is loaded and ready for use. At that point, the script continues.

Copy

Set objShell = WScript.CreateObject("WScript.Shell")

objShell.Run "Calc.exe"

Do Until Success = True

Success = objShell.AppActivate("Calculator")

Wscript.Sleep 1000

Loop

objShell.SendKeys "2"

When the script is determining which application to activate, the given title is compared to the title of each window visible on-screen. If no exact match exists, the AppActivate method sets the focus to the first window whose title begins with the given text. If a window still cannot be found, the first window whose title string ends with the text is given the focus. The partial matching with the leading and trailing text of title bars ensures that AppActivate works with applications, such as Notepad, that display the name of the currently opened document on the title bar. (For example, when you first start Notepad, the window title is Untitled – Notepad, not Notepad.)

This means that when setting the focus to the Calculator, you can use one of the following lines of code:

Copy

objShell.AppActivate "Calculator"

objShell.AppActivate "Calc"

objShell.AppActivate "C"

Of course, this shortcut method of referring to a window can cause problems. For example, suppose you use this line of code:

Copy

objShell.AppActivate "Calc"

If you happen to be working on a Microsoft Word document named Calculations.doc, the keystrokes might be sent to the Word document instead of Calculator.

The script in Listing 3.30 demonstrates a more practical use of the SendKeys method: It starts and sets focus to the Microsoft Management Console (MMC) and then sends keystrokes that cause the Add/Remove Snap-in and Add Standalone Snap-in dialog boxes to be displayed. The script automates the first part of the common task of constructing custom MMC snap-in tools.

Listing 3.30 Sending Keystrokes to a GUI Application

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Copy

Const iNormalFocus = 1

Set objShell = WScript.CreateObject("WScript.Shell")

objShell.Run "mmc.exe",iNormalFocus

Wscript.Sleep 300

objShell.AppActivate "Console1"

Wscript.Sleep 100

objShell.SendKeys "^m"

Wscript.Sleep 100

objShell.SendKeys "{TAB}"

Wscript.Sleep 100

objShell.SendKeys "{TAB}"

Wscript.Sleep 100

objShell.SendKeys "{ENTER}"

Top of page

 

Source: Microsoft Windows 2000 Scripting Guide – Sending Keystrokes to a Program

Categories: Programming

How to attach/detach a database without Enterprise Manager?

February 27, 2012 Leave a comment

Introduction:

Due to various reasons it can be possible that the Enterprise Manager cannot be used to attach/detach a database in SQL. For example when the MSDE version of SQL is used, the Enterprise Manager is not available. In this case MS-Dos can be used to attach/detach the database.

Explanation:

In order to attach/detach a database via MS-Dos follow the steps below:

  1. Go to [Start] [Run] and type CMD followed by [Enter]
  2. type cd\ [Enter] to go to the root C:\
  3. type osql -E [Enter]
  4. now, 1> will appear. The commandline can now be entered.
Attach a database:
  • In the commandline type sp_attach_db ‘databasename’,'C:\path to databases\database.mdf’,'C:\path to databases\database.ldf’ [Enter]
  • In the second line type go [Enter]
  • Now if no message appears the database has been attached succesfully!

Detach a database:
  • In the commandline type sp_detach_db ‘databasename’
  • In the second line type go [Enter]
  • Now if no message appears the database has been detached succesfully!

 

Source: How to attach/detach a database without Enterprise Manager?

Categories: DataBase

Error: Another Version of Microsoft Visual Studio 2008 has been Detected on this System that must be Updated to SP1

February 27, 2012 Leave a comment

Symptoms

While attempting to install the SQL database and management tools from Microsoft on Windows 2008 R2 server that has XenApp 6.0 or later version installed, the following error message appears:

“Another version of Microsoft Visual Studio 2008 has been detected on this system that must be updated to SP1. Please update all Visual Studio 2008 installations to SP1 level, by visiting Microsoft update.”

clip_image001

The following table provides information about where the installation of SQL 2008 database and management tools fails.

Machine Type

SQL 2008 database and management tools: Install

XenApp Installed, Configured on Windows 2008 R2 using SQL Express as data store

Fails

XenApp Installed, Configured on Windows 2008 R2 using SQL Enterprise as data store

Fails

XenApp Installed, NOT Configured on Windows 2008 R2

Fails

Clean Windows 2008 R2 with no XenApp installed

Success

Resolution

Citrix recommends that the SQL database and management tools be installed on a machine that does not have XenApp installed. Once the database and management tools have been installed, connect to the specific database instance by using the Microsoft SQL Server Management Studio, as displayed in the following screen shot:

clip_image002

Alternative installation:

Once XenApp 6.0 is installed, run the following command:

msiexec /i D:\x64\Setup\vs_shell.msi PATCH=D:\x64\Setup\VS90sp1-KB945140.msp /qb (where D:\ is the location of your SQL media)

The other known workaround to get the SQL database and management tools installed on the same computer which is running XenApp 6.0 or later is to use the following registry edit.

Caution! This fix requires you to edit the registry. Using Registry Editor incorrectly can cause serious problems that might require you to reinstall your operating system. Citrix cannot guarantee that problems resulting from the incorrect use of Registry Editor can be solved. Use Registry Editor at your own risk. Be sure to back up the registry before you edit it

1. Open the Registry on XenApp machine using Start > Run > Regedit.

2. Browse for HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS

3. Rename this key to VS_1 or something similar.

4. Install the SQL database and management tools.

5. Rename
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS_1
to
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS

6. Restart.

7. Go to Start > All programs > Microsoft SQL Server 2008 > SQL Server Management Studio and connect to your database instance, as shown in the following screen shot:

clip_image003

This document applies to:

· XenApp 5.0 for Windows Server 2008 x64

· XenApp 5.0 for Windows Server 2008 x86

· XenApp 6.0 for Windows Server 2008 R2

 

Source: CTX128280 – Error: Another Version of Microsoft Visual Studio 2008 has been Detected on this System that must be Updated to SP1 – Citrix Knowledge Center

Categories: Citrix, DataBase

How to kill all sessions that have open connection in a SQL Server Database?

February 27, 2012 Leave a comment

As SQL Server DBAs, many times we need to KILL all Open Sessions against the SQL Server Database to proceed with Maintenance Task, Restore and more…

You can use below different techniques to KILL all open sessions against the database.

Technique – I
Here we will query the SysProcesses table to get the session running against the user database and prepare the dynamic SQL statement to KILL all the connection.

view source

print?

01

DECLARE @DbName nvarchar(50)

02

SET @DbName = N’Write a DB Name here’

03

 

04

DECLARE @EXECSQL varchar(max)

05

SET @EXECSQL = ”

06

 

07

SELECT @EXECSQL = @EXECSQL + ‘Kill ‘ + Convert(varchar, SPId) + ‘;’

08

FROM MASTER..SysProcesses

09

WHERE DBId = DB_ID(@DbName) AND SPId @@SPId

10

 

11

EXEC(@EXECSQL)

Technique – II
Take the database into Single User Mode and execute all the task needs to perform against the databse.

view source

print?

1

ALTER DATABASE [Database Name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE

Once you are finish with all the required task make the database accessible to everyone.

view source

print?

1

ALTER DATABASE [Database Name] SET MULTI_USER

Technique – III
In case of restore the database by replacing existing database, you can take the database OFFLINE and restore it. Restore will bring the database online.

view source

print?

1

ALTER DATABASE [Database Name] SET OFFLINE WITH ROLLBACK IMMEDIATE

view source

print?

1

ALTER DATABASE [Database Name] SET ONLINE

Technique – IV
Go to Activity Monitor, Select the desired database and right click on the database to KILL the process.

clip_image001

 

Source: How to kill all sessions that have open connection in a SQL Server Database? « SQLDBPOOL.COM

Categories: DataBase

Fix: Cannot detach the database ‘DBName’ because it is currently in use. (Microsoft SQL Server, Error: 3703)

February 27, 2012 Leave a comment

When you detach a SQL DB via script/programmatic way you notice SQL fails to detach the DB with error indicating that the DB is still in use.  The same DB detach just works fine when you manually detach the DB before attempting to do it via scripted way.  Once scripting fails, even manual detach fails including restarting the SQL server instance service fails to get the DB released.

 

This scenario particularly exists while you are copying/duplicating/restoring the DB on the SQL server instance.

 

Error:

TITLE: Microsoft SQL Server Management Studio

——————————

Detach database failed for Server ‘TESTSRV2008R2\MyDB’. (Microsoft.SqlServer.Smo)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.50.2500.0+((KJ_PCU_Main).110617-0038+)&EvtSrc=Microsoft.SqlServer.Management.Smo.ExceptionTemplates.FailedOperationExceptionText&EvtID=Detach+database+Server&LinkId=20476

——————————

ADDITIONAL INFORMATION:

An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)

——————————

Cannot detach the database ‘MyDB’ because it is currently in use. (Microsoft SQL Server, Error: 3703)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.50.2500&EvtSrc=MSSQLServer&EvtID=3703&LinkId=20476

——————————

BUTTONS:

OK

——————————

 

Cause and Troubleshooting:

You don’t understand which process is holding the DB in-use. Further to that killing the respective accessing DB processes even won’t help you.  Forcing DB detach/delete with ‘end/close existing connections’ leaves DB in Single user mode.

 

select d.name, d.dbid, spid, login_time, nt_domain, nt_username, loginame

from sysprocesses p inner join sysdatabases d on p.dbid = d.dbid

where d.name like ‘%mydb%’

go

kill 53

go

image

 

 

 

Fix:

 

The fix is to make the DB offline with ‘SET OFFLINE WITH ROLLBACK IMMEDIATE’ setting so that the DB will turn offline immediately and then Detach DB will work fine.  When you attach the DB you can make the DB Online.

 

ALTER DATABASE <DBName> SET OFFLINE WITH ROLLBACK IMMEDIATE

ALTER DATABASE [Database Name] SET ONLINE

 

 

 

 

 

References:

  1. Remove SQL Server database from single-user mode
  2. How to kill all sessions that have open connection in a SQL Server Database? « SQLDBPOOL.COM
Categories: DataBase

Direct Download links for DSC 2012: DISTRICT WISE VACANCY POSITION (DSC-2012) and Community Wise Vacancies List

February 27, 2012 Leave a comment

 

http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/SRIKAKULAM.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/VIZIANAGARAM.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/VISAKHAPATNAM.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/EASTGODAVARI.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/WestGodavari.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/Krishna.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/GUNTUR.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/PRAKASAM.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/NELLORE.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/CHITTOOR.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/KADAPA.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/ANATHAPUR.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/KURNOOL.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/MBNR.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/RANGAREDDY.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/HYDERABAD.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/MEDAK.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/NIZAMABAD.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/ADILABAD.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/KARIMNAGAR.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/WARANGAL.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/KHAMMAM.pdf                                                                      
http://apdsc.cgg.gov.in:80/APDSCJAN2012/GOVT_ZPP_MPP/NALGONADA.pdf

 

Source: Community Wise Vacancies List

Categories: Careers
Follow

Get every new post delivered to your Inbox.

Join 96 other followers