Introduction: Creating Virtual Directories from an ASP Page Using IUSER_xxx Account
Controlling a web site using ADSI is fairly easy (15 Seconds ADSI section). Controlling ADSI can also be done using an ASP page. The real drawback is that in order to make ADSI work in an ASP page, the user requesting the ASP page must be logged on interactively. The user cannot call this ASP page using an IUSER_xxx account, since he is not logged on interactively. Furthermore, if the web site has no permission other than IUSER_xxx, no user can use ADSI in an ASP page because no user is logged on interactively.
The same problem also occurs when implementing some kind of logging mechanism other than IIS NTLM logging mechanism -- IIS can’t be controlled using ADSI. Actually, it can, and we’ll try to see how.
The aim of this article is to create and implement two approaches to overcome the problem.
We’ll focus on:
Creating an Active Server Component using Visual C++ 5.0 to control IIS,
Implementing the Active Server Component using ATL and COM,
Writing a C++ COM code to access ADSI,
Peeking at Unicode,
Using Windows Scripting Host (WSH),
Using third-party products, and more.
We assume that the target machine is NT4.0 Service Pack 3.0 with IIS4.0.
Here’s a checklist of the software we’ll be using.
Windows NT Server 4.0 Service Pack 3
NT Option Pack including IIS 4.0 and Windows Scripting Host (WSH)
Visual C++ 5.0 or Visual C++ 6.0 (Implementation method I)
ASPExec Active Server Component, available online at ServerObjects web site: http://www.serverobjects.com/ (Implementation method II)
CrtVDir.exe, available online from Microsoft Knowledge Base (iwamreg.h Header file for Implementation method I, Executable file for Implementation Method II). See references at the end of the article.
Defining the Problem
To illustrate the problem, we’ll first create an ASP that uses ADSI. The scripts’ goal is to create a virtual directory with only Read permissions, named MyVirtualDir, mapped to C:\temp.
You should have some previous knowledge of ADSI. If you’re not familiar with ADSI, take a look at the references at the end of the article.
First, create a file named demo1.asp as shown below. Save the file in a directory that has script permission (for example, \inetpub\scripts).
demo1.asp
<HTML>
<BODY>
<TITLE>Creating a virtual directory using ASP and ADSI</TITLE>
<%
On Error Resume Next
VirtualDir = "MyVirtualDir"
PhysicalDir = "c:\temp"
Set WebSite = GetObject("IIS://LocalHost/W3svc/1/Root")
If Not IsObject(WebSite) Then
Response.Write "Unable to access root web site<br>"
Response.End
End If
Set vDir = WebSite.Create("IIsWebVirtualDir",VirtualDir)
If (Err <> 0) Then
Response.Write "Unable to create virtual directory<br>"
Response.End
End If
vDir.AccessExecute = FALSE
vDir.AccessScript = FALSE
vDir.AccessWrite = FALSE
vDir.AccessRead = TRUE
vdir.EnableDirBrowsing = FALSE
vDir.Path = PhysicalDir
If (Err <> 0) Then
Response.Write "Unable to bind path to virtual directory<br>"
Response.End
End If
vDir.SetInfo
If (Err <> 0) Then
Response.Write "Unable to save configuration for <b>" & PhysicalDir
Response.Write "</b><br>"
Response.End
End If
Response.Write "Virtual directory <b>" & VirtualDir & "</b> created successfully<br>"
%>
</BODY>
</HTML>
Now, open the Internet Service Manager (MMC), click on the Default Web Site and select Properties (right mouse button). Tab to Directory Security and click the Edit button in the Anonymous Access and Authentication Control. Make sure that the Allow Anonymous-Access checkbox is unchecked (see figure 1).
Figure 1 - Changing Access Permissions to IIS (Web Server)
Assuming demo1.asp is located in /scripts directory point your browser to:
http://localhost/scripts/demo1.asp
Note
Make sure you are logged on as administrator.
If everything goes well, you should get the following response:
Virtual directory MyVirtualDir created successfully
You can also check that the virtual directory was created on the root of your default web server and that it has only Read permissions (open MMC to make sure).
If you already have the directory MyVirtualDir mapped in your web site, you’ll probably get the following error:
Unable to create virtual directory
So open MMC and remove the MyVirtualDir directory so that you can try the ASP script.
Voila – it works!
Ah, but no so fast. Now open MMC and check the Allow Anonymous Access option. If you try accessing the demo1.asp page, you’ll get the following response:
Unable to access root web site
What just happened here? When you accessed the demo1.asp page with Allow Anonymous Access unchecked, you were actually logging into the site using your own permissions, i.e., the permissions that you're using while logged on to NT Server, meaning Administrator privileges. On the other hand, when the Allow Anonymous option was checked you were actually logging using the IUSER_xxx account. And this account has no privileges to administrate IIS.
Implementation Method 1
Out first method for overcoming this problem is to create an Active Server Component using Visual C++ 5.0 (or higher.) Your first question would probably be – “Yes but why should this work? You’re still logged on as IUSER_xxx?” True enough, but you see, an Active Server Component (DLL) runs in the security context of the client. In our case, the client is IIS (actually inetsrv.exe) and IIS has access permission to change IIS behavior. Meaning, it can add and delete virtual directories and basically, administrate IIS.
Well, let’s get down to work.
Starting and Stopping IIS
In order to reload an active server component, IIS must be shut down. To obtain this, both the service’s IIS Admin Service (IISADMIN) and World Wide Web Publishing Service (W3SVC) must be stopped. You don’t have to stop either the FTP Publishing Service or the Gopher Publishing Service, however.
Since you’ll be doing a lot of stopping and starting IIS, you must conceive of a better way to do this than My Computer | Control Panel | Service | Stop. One approach to ease these tasks is to create shortcuts. Here’s what you should do:
Create two batch/command files and place them somewhere on your hard disk.
startiis.cmd
net start w3svc
stopiis.cmd
net stop iisadmin /y
The first batch file (startiis.cmd) starts the W3SVC, but since this service is dependent upon the IISADMIN service, the IISADMIN service is automatically started. The second batch file (stopiis.cmd) tells the process IISADMIN to stop, but stopping it will cause W3SVC to stop as well. Therefore, IISAdmin asks you if you want to stop W3SVC as well. The /y switch automatically answers this question with “of course, sure, go ahead, I said so, didn’t I!”
Create two shortcuts on your desktop, one for startiis.cmd and the other for stopiis.cmd. Right click the startiis.cmd shortcut and select Properties. Tab to the shortcut property page and press CTRL-ALT-S in the shortcut key edit box. Do the same for stopiis.cmd, only this time assign CTRL-ALT-P to it.
Now starting or stopping IIS is as simple as pressing CTRL-ALT-P or CTRL-ALT-S.
Another approach is to add a tool to Developer Studio. To do this click Tools | Customize and tab to the Tools page. Create a new entry and name it “Start Server.” In the Command edit box type “net.exe” and in the Arguments edit box type “start w3svc”. If you check the Use Output Window, you’ll be able to see the results in Developer Studio output window. Now, add another entry and name it “Stop Server,” with command “net.exe” and arguments “stop iisadmin /y.” Also check the use output window. To stop or start IIS all you have to do is select Tools | Start Server or Tools | Stop Server from Developer Studio.
Figure 2 - Starting and Stopping IIS from Visual C++
If you really want to automate things, add the "net stop iisadmin /y" to the Project | Settings | Pre-link Step and “net start w3svc” to the Project | Settings | Post-build Step (see figure 3). Once you’ve done that, every time you compile your component, Developer Studio will stop IIS, link and register the component and then restart IIS. However, I found this method a little bit too slow to use, since I often build the code without actually testing it. So there’s no need to stop and start IIS, I simply stop it when I need to and start it only when I want to test the component.
Figure 3 - Automating the Task of Starting and Stopping IIS from Visual C++
Creating the Project
Creating an ATL COM Control
Open VC and create a new ATL COM AppWizard project. Name the project MyADSI and click OK. Since we’ll be making an Active Server Component, we want the server type to be a DLL. For the same reason, we want the project to allow the merging of proxy/stub code, so select this option as well. If you intend on using some MFC classes, click the Support MFC option. (I use them from time to time during development cycle, especially the CString, CstringArray, and CObArray classes or when I’m accessing MFC classes like CSockets.) Bear in mind that adding MFC support increases the size of your DLL.
In this example, the same object with MFC support (even if you’re not actually using any MFC code) causes the DLL to be 5 times larger (17.5K when not using MFC and 102K when using it.) It seems that MFC is just an overhead (not a factor/multiplier) so when your DLL weighs 700K without MFC, it would probably weigh about 780K with MFC, but I haven’t tested this hypothesis yet. Also, when using MFC, you should decide whether you’ll be linking it statically or dynamically (Project | Settings | General.) If it’s statically linked, then again your DLL size increases. If not, you must also supply the MFCxxx.DLL files when distributing the object.
Once you’re done, click Finish and then OK.
Header Files
VC5 was released before the NT Option Pack (including IIS4) was released. Therefore, according to the readme.txt file located in \inetpub\iisamples\sdk\include,
"The IIS SDK is redistributing two Win32 rpc header files: rpcndr.h
and rpcproxy.h. It is necessary to replace the existing versions
of these header files on your NT 4.0 system or in your VC5++ environment
to compile and link C++ projects built using the new IIS 4.0 Header Files."
The easiest way to do this is to add the location of the header files VC5 will use. To do so, click Project | Settings | Settings-for | All-configurations and tab to the C/C++ property page. Choose Preprocessor from the Category drop-down list. In the Additional-include-directories edit box, type the location of your newer IIS 4.0 include files. They’re usually located in c:\inetpub\iissamples\sdk\include (see figure 1).
Figure 4 - Specifying include Directories for IIS 4.0
Well, our work here is not done yet. We need one more file, this is the iwamreg.h header file, used when accessing COM to administrate IIS. You must download this header file from Microsoft online. The file is a part of the knowledge base article and is bundled with the source code for the CrtVDir knowledge base sample article, on which most of this work is based. Download the file CrtVDirD.exe (a self-extracting zip file) and copy the header file iwamreg.h to c:\inetpub\iissamples\sdk\include. See the references at the end of the article.
Adding Active Server Pages Support
The next step is to add a new ATL Object, the one that supports ASP. From the menu bar, select Insert | New ATL Object | Objects | ActiveX Server Component and click Next. The ATL Object Wizard Properties shows up. For the short name, type Control.
Note that in VC5, you also must change the name of the ProgID; highlight the first Control in Control.Control and rename it to MyADSI.Control. Tab to the ASP options property page and deselect every intrinsic object except the Response object (we’ll be using this to write output to the ASP page.) If you intend on using other intrinsic ASP objects, select them as well. Make sure the OnStartPage/OnEndPage checkbox is checked. Click OK when you’re done.
Writing the Component Code Using COM, ADSI, and Unicode
COM
We won’t be focusing on COM and what it does, rather on how to use it when writing an Active Server Component. COM is the way by which an Active Server Component lets VBA (the ASP page) use its functions (methods) and variables (properties.) Our component will expose the following methods:
Method
What it does
CreateVDir (physicalPath, VirtualPath)
Creates a virtual directory
ExistsVDir (virtualPath)
Checks for existence of a virtual directory
DeleteVDir (virtualPath)
Deletes a virtual directory
Help
Displays help information
It will also expose the following properties:
Property
What it does
Site
Determines on which site operation will take place (the default site is 1)
Permissions
Determines the directory permissions when creating a virtual directory
To view what we have achieved so far, click the ClassView tab in your workspace window. You should be able to see a tree. Its root is named after the project name (MyADSI), and it has three branches. One is CControl, another is Icontrol, and the last is Globals. The CControl is where the actual code goes—the implementation in C/C++. The IControl defines the methods and properties of you component—the ones that are exposed to the calling ASP script. The Globals branch contains global functions and global variable declarations.
To add the methods and properties I’ve mentioned, highlight the IControl branch. Right-click it and select Add Method. In the Method Name edit box, type CreateVDir. In the Parameters field, type [in] BSTR physicalPath, [in] BSTR virtualPath, [out, retval] BOOL *pVal. Notice that the order and case of this line is important (i.e., you must type retval and not retVal or you’ll have trouble compiling the project, also the [out, retval] parameter must be last.) What you’ve just done is declared a method for your component. It gets two Unicode strings as input (physicalPath and virtualPath), and returns a Boolean value. Repeat this operation for the following methods:
ExistsVDir
[in] BSTR virtualPath, [out, retval] BOOL *pVal
DeleteVDir
[in] BSTR virtualPath, [out, retval] BOOL *pVal
Help
{ no parameters - don’t type anything }
For every method you’ve created, VC automatically creates a function in the CControl class. If you expand the CControl branch in the ClassView, you’ll see a branch named IControl. This branch holds the implementation of the methods the component exposes. Notice that there are also some other functions in CControl. These functions, whether private or public, are hidden from the COM interface (and the ASP page.)
We continue by adding properties to the component. Again, highlight the IControl branch and right-click it. Select Add Property. This time you get a Property dialog box. For the Property Type drop-down box, select short and in the Property-name edit box, type Site. Make sure that the Get and Put functions are selected (see figure 5.) Repeat this operation to create the Permissions property (short type as well.)
Figure 5 - Adding Properties to the Component
Again, VC has already written some code for you. If you click the IControl branch in Ccontrol,you’ll see four more functions: get_Permissions, put_Permissions, get_Site, and put_Site. These are the C/C++ implementation for changing the property of our control.
Our next step is to create the actual functions that will perform the tasks at hand, e.g., create virtual directories, delete them, ask for their existence, manage properties, and, of course, print some help.
The first thing we need to understand is how to manipulate IIS. First, we declare a COM object of type IMSAdminBase. This COM pointer will let us access IIS:
CComPtr m_pAdminBase;
We place this declaration in the private section of the CControl header file.
To create a virtual directory using COM pointer we follow these steps:
Call CoCreateInstance to initialize our COM pointer.
Open the Metabase related to IIS.
Create a key for the virtual path in our Web Server.
Set the key to be a virtual path.
Set permissions for the virtual path.
Set the mapping of the virtual path to the physical path.
Close the Metabase related to IIS.
Call SaveData to store modifications.
Release the COM pointer.
Notice how circular our operations are: at the beginning, we call CoCreateInstance, and our last step is Release, to release the instance (steps I and IX). The same goes for opening and closing the Metabase (steps II and VII). If for some reason we have to stop at one of the steps before I (an error occurred), we must call all the closing functions for the functions we’ve already called. For example, if we stop at step II, we must call Release since CoCreateInstance was already called.
A rather straightforward implementation of this can be found in InternalCreateVDir (see source codes). This function is called from CreateVDir (the one that is exposed to COM).
The following outline the steps needed to delete a virtual directory:
Call CoCreateInstance to initialize our COM pointer.
Open the Metabase related to IIS.
Delete the key related with the virtual path.
Close the Metabase related to IIS.
Call SaveData to store modifications.
Release the COM pointer.
Again, notice how circular our operations are. Implementation of these steps can be found in InternalDeleteVDir. This function is called from DeleteVDir (the one that is exposed to COM).
To check for the existence of a directory we follow these steps:
Call CoCreateInstance to initialize our COM pointer.
Open the Metabase related to IIS.
Open the key related with the virtual path. (If we can open it, the directory exists.)
Close the key related with the virtual path.
Close the Metabase.
Release the COM pointer.
Implementation of these steps can be found in InternalExistsVDir. This function is called from ExistsVDir (the one that is exposed to COM).
If you examine the CrtVDir.cpp file (the source code in Microsoft’s Knowledge Base article - see references), you’ll notice that there is a call to CoInitialize before getting the COM pointer. This function is meant for applications that want to access COM. They first must initialize the COM library. In our case, however, we use a DLL (not an application) and the process which accessed us must have already initialized COM, otherwise the component’s methods and properties wouldn’t have been called (actually it was inetsrv.exe – IIS itself). This means that we needn’t call CoInitialize(). However, calling CoInitialize() will not affect the behavior of our component. It will not fail.
Our last method is the Help method which takes no arguments and prints help regarding our component to the calling ASP page. The function uses the intrinsic object Response (m_pResponse private variable in CControl) to print the help information.
Unicode
If you look closely in the code, you’ll find many strange functions, such as _tcscpy, _tcscat, _stprintf, and _ttoi, and many strange data types, such as _TCHAR, TPSTR, etc. These functions and declarations are actually the Unicode version of the known strcpy, strcat, sprintf, and atoi functions, and char and LPSTR data types, respectively (every ‘str’ is replace with ‘_tcs’).
Unicode is a sort of an extension for ASCII characters. Every character is made out of 16 bits (2 bytes) to accommodate for multilanguage character sets (accented letters, Hebrew, and Arabic, Thai, etc.).
The reason for using Unicode is that you must. IIS and ADSI force you to use Unicode characters (or is it NT?) Actually the Unicode versions of the string manipulation functions are wcscpy, wcscat, and wsprintf functions, and wtoi and wchar_t for data types declaration (every ‘str’ is replaced with ‘wcs’). However, Microsoft strongly suggests that you use macros instead of the wcs (Wide Character Set) functions. Their reason is that there is another (yes, another) character set called MBCS (Multibyte Character Set.) The _tcs functions are actually macros that map each function according to a definition declaration. If you define _Unicode, then all the _tcs functions are mapped to a wcs function. If you define _MBCS then all the _tcs functions are mapped to their multibyte version (mbs.)
One last thing regarding Unicode is that you must compile the project in one of its Unicode versions. For example, to compile in release mode, select Build | Set Active Configuration | Win32 Unicode Release MinSize.
Testing the Component
Registering the Active Server Component
If you’ve used VC to compile and test the project, the MyADSI active server component is probably registered in the registry. However, if you’ve just downloaded the component, or want to run it on a different machine, you must register the component using regsvr32.exe:
Regsvr32 MyADSI.dll
Using the Active Server Component in an ASP Page
Our control’s name is comprised of two names, the project name (MyADSI) and the COM class name (Control), to form MyADSI.Control.1. To call it from an ASP page you must first ask the server to create an object of that name and store it in a variable (MyADSIControl) as follows:
<% Set MyADSIControl = Server.CreateObject(“MyADSI.Control.1”) %>
Accessing the components methods and properties is done using the dot (.) operator: For example, to create a virtual directory we call:
The same goes for all the methods and properties we’ve defined.
To finally test the component, create an ASP page in a directory on the server that has execute permissions. Create a file named test1.asp as follows:
test1.asp
<HTML>
<HEAD><TITLE>Testing MyADSI Control</TITLE></HEAD>
<BODY>
<%
Set MyADSIControl=Server.CreateObject("MyADSI.Control.1")
Sub Exists(str)
Response.Write "Virtual directory " & str
If MyADSIControl.ExistsVDir(str) Then
Response.Write " exists<br>"
Else
Response.Write " does not exist<br>"
End If
End Sub
physicalDir = "c:\temp"
virtualDir = "MyVirtualDir"
MyADSIControl.Site = 1
Response.Write "<hr>" & vbCrLf
Exists(virtualDir)
done_ok = MyADSIControl.DeleteVDir(virtualDir)
If done_ok Then
Response.Write "Deleted virtual directory "
Response.Write virtualDir & "<br>" & vbCrLf
Else
Response.Write "Error deleting vitrual directory "
Response.Write virtualDir & "<br>" & vbCrLf
End If
Exists(virtualDir)
MyADSIControl.Permissions = 1
done_ok = MyADSIControl.CreateVDir(physicalDir, virtualDir)
If done_ok Then
Response.Write "Created vitrual directory " & virtualDir
Response.Write " mapped to " & physicalDir & "<br>" & vbCrLf
Else
Response.Write "Error creating vitrual directory "
Response.Write virtualDir & "<br>" & vbCrLf
End If
Exists(virtualDir)
Response.Write "<hr>" & vbCrLf
MyADSIControl.Help
%>
</BODY>
</HTML>
Running this page, you should get one of the following typical responses (I’ve omitted the Help() method output).
If MyVirtualDir exists:
Virtual directory MyVirtualDir exists
Deleted virtual directory MyVirtualDir
Virtual directory MyVirtualDir does not exist
Created vitrual directory MyVirtualDir mapped to c:\temp
Virtual directory MyVirtualDir exists
If MyVirtualDir does not exist:
Virtual directory MyVirtualDir does not exist
Error deleting vitrual directory MyVirtualDir
Virtual directory MyVirtualDir does not exist
Created vitrual directory MyVirtualDir mapped to c:\temp
Virtual directory MyVirtualDir exists
Implementation Method 2: Executing Command Line Programs from an ASP Page
The second approach for overcoming the IUSER_xxx accessing IIS problem is to call a command-line utility to manipulate IIS structure. To accomplish this, we do two things: (1) Devise of a method to call a command-line utility from an ASP page, and (2) Create a command-line utility to manipulate IIS.
The method to call a command-line utility is quite simple. Just write a generic Active Server Component (DLL) that calls command-line utilities. As mentioned in implementation method 1, the Active Server Component (DLL) runs in the security context of the client (meaning inetsrv.exe) and therefore can access IIS structure.
Fortunately, someone has already written an active server component to do just that. The one we’re going to use is ASPExec from ServerObjects Inc. (see references at the end of the article). The main reason for using it is it’s free!
As for the second task of writing a command-line utility for manipulating IIS, we’ll also use some readily available resources. One option is the same CrtVDir.exe application (see references).
The second option is to use the Windows Scripting Host (WSH.) WSH is actually a VBA script which can be run from the command line using either CScript or Wscript executables.
We won’t be dealing with deleting or checking for the existence of virtual directories, just creating them.
Accessing IIS from the Command Line
First of all, let’s try to access IIS from the command line.
The most straightforward way of doing this is downloading CrtVDird.exe. After you download this file, compile it using VC5 (it doesn’t compile easily on VC6 – you have to do some modifications to make it work) and run it in the Command prompt. You should get the following result:
Usage:
CrtVDir.exe CD [] []
CrtVDir.exe RD []
CrtVDir.exe CA
CrtVDir.exe RA
path - physical path which Virtual Directory will refer to
name - name for virtual directory
metabasepath - full metabase path to the relevant key: w3svc/1/root/myvr
permissions - add desired constants below together
1 = Read Access
2 = Write Access
4 = Execute Access (including Script)
512 = Script Access
site - defaults to 1 if not supplied
INPROC|OOP - application will run in-process of out-of-process
Now, run it with parameters to create a virtual directory named MyVirtualDir, mapped to c:\temp:
Crtvdir CD c:\temp MyVirtualDir
Note: You must type capital CD.
Another option is using the Windows Scripting Host. As mentioned before, WSH is actually a way to run VBA scripts from within NT. WSH was introduced in NT Option Pack 4 and has numerous examples (usually located in c:\winnt\system32\inetsrv\adminsamples) and help files relating to the subject (see references).
First, let’s create a script for adding virtual directories. Create a file named Cvdir.vbs and type the following code into it:
Cvdir.vbs
'--------------------------------------------------------------------
' Usage: cvdir virtualDir,physicalDir
' Example: cvdir MyVirtualDir,c:\temp
'--------------------------------------------------------------------
' Force explicit declaration of all variables.
Option Explicit
Dim oArgs, Params
' Read parameters passed from the command line
Set oArgs = WScript.Arguments
If oArgs.Count<>1 Then
Die("Incorrect number of arguments passed to cvdir.vbs" & vbNewLine & "Usage: cvdir virtualDir,physicalDir")
End If
' Make sure we got all four parameters
Params=Split(oArgs(0), ",", -1, 1)
If UBound(Params)<>1 Then
Die("Parameter passing is not in the form: virtualDir,physicalDir")
End If
' Store parameters passed
Dim virtualDir, physicalDir
virtualDir=Params(0)
physicalDir=Params(1)
' Get WebSite object
Dim WebSite
set WebSite = GetObject("IIS://LocalHost/W3svc/1")
If Not IsObject(WebSite) Then
Die("Unable to access WebSite object")
End If
' Get virtual root directory
Dim vRoot
set vRoot = WebSite.GetObject("IIsWebVirtualDir", "Root")
If (Err <> 0) Then
Die("Unable to access root for " & WebSite.ADsPath)
End If
' Create a new virtual root
Dim vDir
Set vDir = vRoot.Create("IIsWebVirtualDir",virtualDir)
If (Err <> 0) Then
Die "Unable to create " & vRoot.ADsPath & "/" & virtualDir &"."
End If
' Set the new virtual directory path
vDir.AccessExecute = false
vDir.AccessScript = false
vDir.AccessWrite = false
vDir.AccessRead = true
vdir.EnableDirBrowsing = false
vDir.Path = physicalDir
If (Err <> 0) Then
Die "Unable to bind path " & virtualDir & " to " & physicalDir & ". Path may be invalid."
End If
' Inform the IIS of the new virtual directory
vDir.SetInfo
If (Err <> 0) Then
Die "Unable to save configuration for " & physicalDir & "."
End If
Sub Die(Msg)
WScript.Echo Now & ". Error Code: " & Hex(Err) & " - " & Msg
WScript.Quit (1)
End Sub
From the command-line prompt type:
cscript.exe Cvdir.bus NewVirDir c:\temp
If everything goes well, you should be able to see that a new virtual directory was created mapped to c:\temp (open MMC to make sure).
The same method can also be applied to deleting virtual directories and all sorts of IIS manipulations. See the references at the end of the article.
Calling an Application from an ASP Page
First of all, you should download a component that can call applications from an ASP page. It is beyond the scope of this article to create such a component.
Searching the Internet, I’ve come up with a component that does that. The component is ASPExec from ServerObjects Inc. ( http://www.serverobject.com) and is provided for free ( support is not free, however). Read the ASPExec documentation carefully and install it.
The method we’re interested in is:
ExecuteDosApp
Executes the specified app as a DOS app and returns stdio as string
And the properties we’ll be using are:
Application
Set the path (optional) and exe/com filename
Now write the following imp1.asp ASP page:
imp1.asp
<HTML>
<HEAD><TITLE>Testing Implementation Method II</TITLE></HEAD>
<BODY>
<%
Set Executor = Server.CreateObject("ASPExec.Execute")
' Note: make sure that you type the full path to cvdir.vbs !
Executor.Application = "CScript.exe c:\temp\cvdir.vbs MyVirtualDir,c:\temp"
Executor.ShowWindow = True
Executor.ExecuteDosApp
%>
Check to see that <b>MyVirtualDir</b> was created succesfully
</BODY>
</HTML>
Note
imp1.asp assumes that cvdir.vbs is located in c:\temp.
Now save it to a directory with script permissions. Access the page (assuming it’s in /scripts) at http://localhost/scripts/imp1.asp. You should be able to see the new virtual directory created. Oopen MMC and make sure!
Further Reading and References
This article draws a lot from two articles available online:
The following are good references to subjects discussed in this article.
NT Option Pack Documentation on IIS Administration, ADSI and Windows Scripting Host (Contents | Microsoft Internet Information Server | Scripter’s Reference | Windows Scripting Host Programmer's Reference and Contents | Microsoft Internet Information Server | Programmer’s Reference | IIS Administration)
Examine the iwamreg.h header file. You’ll be able to see all the administration functions relating to IIS. With a little knowledgeof ADSI you can easily implement them for doing tasks more complicated than creating and deleting a virtual directory.
Tool Parts provide an interface for Web Part properties well beyond the capabilities of the default property pane. In this article Gayan Peiris shows how to customize Web Parts with custom Tool Parts. [Read This Article][Top]
This article demonstrates how to create a reusable component in ASP.NET 2.0 and then consume it from an ASP.NET page. Also learn how the ObjectDataSource control can be used to directly bind the output of an object to the controls in an ASP.NET page and how precompilation can be used to increase the performance of the Web application and catch compilation errors. [Read This Article][Top]
Browser Helper Objects (BHOs) are COM components that communicate with Internet Explorer to enrich the browsing experience. Michele Leroux Bustamante returns to the world of COM to show you how to build a managed BHO with the help of the .NET Framework's COM interoperability features. [Read This Article][Top]
In addition to creating custom Web Parts for SharePoint Portal Server, developers can actually create their own custom properties to further enhance Web Part appearance and behavior. Gayan Peiris explains the process and provides all the necessary code. [Read This Article][Top]
Accessing shared resources is a challenge for many ASP.NET developers. Tony Arslan explains how a simple serviced component can solve this infamous problem. [Read This Article][Top]
Using callbacks and function pointers in VB can be risky and complicated. Ben Garcia explains his work-around for the function pointer issue he encountered while creating the VB version of his SNMP component. [Read This Article][Top]
In part two of this intriguing article series, Ben Garcia shows how to build an updated and improved SNMP component in VC++ AND VB, and he briefly explains why limitations in VB make VC++ a better language for developing this type of application. [Read This Article][Top]
Ben Garcia sheds some light on the Simple Network Management Protocol
(SNMP). First he provides a history of SNMP, then he dives right into its
architecture. Finally, he shows how to build a COM component that
communicates with SNMP-enabled devices. [Read This Article][Top]
Paul Apostolos begins his series on using Web services and the MSComm32.OCX
component to access caller id information from a Web page. In part 1, learn how to write the Visual Basic program that runs on the server and updates a database with incoming callers.
[Read This Article][Top]
Doug Dean explains different methods of retrieving and manipulating data from a database in a VB DLL so that it is ready to be rendered in a browser. [Read This Article][Top]
Mailing List
Want to receive email when the next article is published? Just Click Here to sign up.