Microsoft KB Archive/299692

= How to upload files to a Web server by using ASP =

Article ID: 299692

Article Last Modified on 7/8/2005

-

APPLIES TO


 * Microsoft Active Server Pages 4.0
 * Microsoft Internet Information Server 4.0
 * Microsoft Internet Information Services 5.0

-



This article was previously published under Q299692





For a Microsoft Visual Basic .NET version of this article, see 315832.



IN THIS TASK

 * SUMMARY
 * Requirements
 * Microsoft Visual Basic 6 Project Setup and Code
 * ASP Code
 * Set Up the Server
 * Upload a File
 * Troubleshooting



SUMMARY
This article describes how to enable your Web server to receive file transfers from Microsoft Active Server Pages (ASP) pages by using a server-side Microsoft COM+ component.

back to the top

Requirements

 * 1) Microsoft Windows 2000 with Microsoft Internet Information Server 5.0 (IIS) installed and configured
 * 2) If your development computer is a different computer than the server, you must have a valid network or Internet connection to the server that hosts the ASP pages.

back to the top

Microsoft Visual Basic 6 Project Setup and Code
 Start Visual Basic, and then start a new ActiveX DLL project. Name the project ASPFileUpload . Change the name of Class1 to File . On the Project menu, click References. In the References dialog box, click to select the following options, and then click OK:  Visual Basic For Applications</li> Visual Basic runtime objects and procedures</li> Visual Basic objects and procedures</li> OLE Automation</li> COM+ Services Type Library</li> Microsoft Active Server Pages Object Library</li> Microsoft Scripting Runtime</li></ul> </li> On the Project menu, click ASPFileUpload Properties.</li> In the Project Properties dialog box, click to select Unattended Execution and Retained In Memory, and then click OK.</li>  Paste the following code to File.cls: Option Explicit

Const ERR_INVALID_FILENAME = vbObjectError + 1000 Const ERR_INVALID_TARGET = vbObjectError + 1001 Const ERR_FILE_EXISTS = vbObjectError + 1002 Const ERR_UPLOAD_CALLED = vbObjectError + 1003 Const VB_ERR_PATH_NOT_FOUND = 76

Private m_objContext As ObjectContext Private m_objRequest As ASPTypeLibrary.Request

Private m_strTarget As String Private m_strFileName As String Private m_blnOverWrite As Boolean Private m_blnUploaded As Boolean Private m_lngTotalBytes As Long

'All other form elements go here. Private m_formCol As Scripting.Dictionary

Implements ObjectControl

Private Function ObjectControl_CanBePooled As Boolean ObjectControl_CanBePooled = False End Function

Private Sub ObjectControl_Activate Set m_objContext = GetObjectContext Set m_objRequest = m_objContext(&quot;Request&quot;) Set m_formCol = New Scripting.Dictionary End Sub

Private Sub ObjectControl_Deactivate Set m_objContext = Nothing Set m_objRequest = Nothing Set m_formCol = Nothing End Sub

Public Sub Upload Const DEFAULT_CHUNK_SIZE = 262144 '256kb Dim bytBeginOfChunk As Byte Dim bytEndOfChunk As Byte Dim bytBeginOfName As Byte Dim bytEndOfName As Byte Dim bytBeginOfFile As Byte Dim bytEndOfFile As Byte Dim bytBeginOfValue As Byte Dim bytEndOfValue As Byte Dim bytName As Byte Dim bytValue As Byte Dim bytThisChunk As Byte Dim bytFileName As Byte Dim lngBeginOfChunk As Long Dim lngEndOfChunk As Long Dim lngBeginOfAttribute As Long Dim lngEndOfAttribute As Long Dim lngBeginOfValue As Long Dim lngEndOfValue As Long Dim blnEndOfData As Boolean Dim lngChunkSize As Long Dim lngBytesLeft As Long Dim lngFileNum As Long Dim strFileName As String On Error GoTo UploadErr If Uploaded Then Err.Raise ERR_UPLOAD_CALLED, App.Title, &quot;The Upload method has already been called.&quot; End If bytBeginOfChunk = StrConv(&quot;-&quot;, vbFromUnicode) bytEndOfChunk = StrConv(&quot;-&quot;, vbFromUnicode) bytBeginOfName = StrConv(&quot;name=&quot;, vbFromUnicode) & ChrB(34) bytEndOfName = ChrB(34) bytBeginOfFile = StrConv(&quot;filename=&quot;, vbFromUnicode) & ChrB(34) bytEndOfFile = ChrB(34) bytBeginOfValue = ChrB(13) & ChrB(10) & ChrB(13) & ChrB(10) bytEndOfValue = ChrB(13) & ChrB(10) & StrConv(&quot;-&quot;, vbFromUnicode) 'Initialize the chunk size. If m_objRequest.TotalBytes <= DEFAULT_CHUNK_SIZE Then lngChunkSize = m_objRequest.TotalBytes Else lngChunkSize = DEFAULT_CHUNK_SIZE End If 'Get the chunk from the request object. bytThisChunk = m_objRequest.BinaryRead(CVar(lngChunkSize))

'Initialize the value. lngBeginOfChunk = 1 'Repeat until the end of the data. Do While Not blnEndOfData 'Begin the chunk. lngBeginOfChunk = InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfChunk) + UBound(bytBeginOfChunk) 'Get name of the item. lngBeginOfAttribute = InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfName) + UBound(bytBeginOfName) + 1 lngEndOfAttribute = InStrB(lngBeginOfAttribute, bytThisChunk, bytEndOfName) bytName = MidB(bytThisChunk, lngBeginOfAttribute, lngEndOfAttribute - lngBeginOfAttribute) 'Get the value of the item. lngBeginOfValue = InStrB(lngEndOfAttribute, bytThisChunk, bytBeginOfValue, vbBinaryCompare) + UBound(bytBeginOfValue) + 1 lngEndOfValue = InStrB(lngBeginOfValue, bytThisChunk, bytEndOfValue, vbBinaryCompare) If lngEndOfValue = 0 Then 'The item extends the past current chunk. bytValue = MidB(bytThisChunk, lngBeginOfValue, lngChunkSize) Else 'The item value exists in the current chunk. bytValue = MidB(bytThisChunk, lngBeginOfValue, lngEndOfValue - lngBeginOfValue) End If   If UCase(StrConv(bytName, vbUnicode)) = &quot;FILE&quot; Then lngBeginOfAttribute = InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfFile, vbBinaryCompare) + UBound(bytBeginOfFile) + 1 lngEndOfAttribute = InStrB(lngBeginOfAttribute, bytThisChunk, bytEndOfFile, vbBinaryCompare) bytFileName = MidB(bytThisChunk, lngBeginOfAttribute, lngEndOfAttribute - lngBeginOfAttribute) If UBound(bytFileName) < 0 Or UBound(bytValue) < 0 Then Err.Raise ERR_INVALID_FILENAME, App.Title, &quot;Invalid File Name.&quot; End If     If Me.Target = &quot;&quot; Then Err.Raise ERR_INVALID_TARGET, App.Title, &quot;Invalid Target.&quot; End If     'Use the original file name. If Me.FileName = &quot;&quot; Then 'Trim the path from the file name. While InStrB(1, bytFileName, StrConv(&quot;\&quot;, vbFromUnicode), vbBinaryCompare) > 0 bytFileName = MidB(bytFileName, InStrB(1, bytFileName, StrConv(&quot;\&quot;, vbFromUnicode)) + 1) Wend 'Set the property. Me.FileName = StrConv(bytFileName, vbUnicode) 'Convert the byte to Unicode. strFileName = Me.Target & Me.FileName Else strFileName = Me.Target & Me.FileName End If     'Check for overwrite. If Me.OverWrite Then 'This is the hack check. Make sure that wildcard characters cannot be used. If Not InStr(1, strFileName, &quot;*&quot;) Then If FileExists(strFileName) Then Kill strFileName End If       Else Err.Raise ERR_INVALID_FILENAME, App.Title, &quot;The specified file name appears to be invalid.&quot; End If     Else If FileExists(strFileName) Then Err.Raise ERR_FILE_EXISTS, App.Title, &quot;The file already exists.&quot; End If     End If      lngFileNum = FreeFile Open strFileName For Binary Access Write As #lngFileNum 'Write the file to the destination directory. Put #lngFileNum,, bytValue

'This chunk is empty. Therefore, get a new chunk. lngBytesLeft = m_objRequest.TotalBytes - lngChunkSize 'Start the chunking machine. Do While lngBytesLeft > 0 'Get a new chunk. bytThisChunk = m_objRequest.BinaryRead(CVar(lngChunkSize)) lngEndOfValue = InStrB(1, bytThisChunk, bytEndOfValue, vbBinaryCompare) If lngEndOfValue > 0 Then 'The item value exists in the current chunk. bytThisChunk = MidB(bytThisChunk, 1, lngEndOfValue - 1) End If         'Append the chunk to the file. Put #lngFileNum,, bytThisChunk lngBytesLeft = lngBytesLeft - lngChunkSize If lngBytesLeft < lngChunkSize Then lngChunkSize = lngBytesLeft End If       Loop Close #lngFileNum TotalBytes = FileLen(strFileName) ' Exit Do    Else If UCase(StrConv(bytName, vbUnicode)) = &quot;SAVEAS&quot; Then Me.FileName = StrConv(bytValue, vbUnicode) Else 'form field other than file, such as textboxes If UBound(bytValue) > 0 And UBound(bytName) > 0 Then m_formCol.Add StrConv(bytName, vbUnicode), StrConv(bytValue, vbUnicode) Else m_formCol.Add StrConv(bytName, vbUnicode), &quot;&quot; End If     End If     End If    'Get the next chunk. lngBeginOfChunk = lngEndOfValue If InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfName, vbBinaryCompare) = 0 Then blnEndOfData = True End If Loop

Uploaded = True Exit Sub UploadErr: If Err.Number = VB_ERR_PATH_NOT_FOUND Then Err.Raise ERR_INVALID_TARGET, App.Title, &quot;The Target specified does not exist.&quot; Else Err.Raise Err.Number, Err.Source, Err.Description End If End Sub

Public Property Get Form As Collection Set Form = m_formCol End Property Public Property Get FileName As String FileName = m_strFileName End Property

Public Property Let FileName(ByVal strNewValue As String) If Uploaded Then Err.Raise ERR_UPLOAD_CALLED, App.Title, &quot;The Upload method has already been called.&quot; Else m_strFileName = strNewValue End If End Property

Public Property Get OverWrite As Boolean OverWrite = m_blnOverWrite End Property

Public Property Let OverWrite(ByVal blnNewValue As Boolean) If Uploaded Then Err.Raise ERR_UPLOAD_CALLED, App.Title, &quot;The Upload method has already been called.&quot; Else m_blnOverWrite = blnNewValue End If End Property

Private Property Get Uploaded As Boolean Uploaded = m_blnUploaded End Property

Private Property Let Uploaded(ByVal blnNewValue As Boolean) m_blnUploaded = blnNewValue End Property

Public Property Get Target As String Target = m_strTarget End Property

Public Property Let Target(ByVal NewValue As String) If Uploaded Then Err.Raise ERR_UPLOAD_CALLED, App.Title, &quot;The Upload method has already been called.&quot; Else m_strTarget = NewValue End If End Property

Private Function FileExists(ByVal FileName As String) As Boolean On Error GoTo FileExistsErr FileLen FileName FileExists = True Exit Function FileExistsErr: If Err.Number = VB_ERR_PATH_NOT_FOUND Then FileExists = False End If End Function

Public Property Get TotalBytes As Long TotalBytes = m_lngTotalBytes End Property

Private Property Let TotalBytes(ByVal NewValue As Long) m_lngTotalBytes = NewValue End Property </li> Compile the project</li></ol>

back to the top

ASP Code
<ol>  Paste the following code to an editor such as Notepad or Microsoft Visual Interdev, and then save it as PostFile.asp : <%@ Language=VBScript %> <form enctype=&quot;multipart/form-data&quot; action=&quot;uploadfile.asp&quot; method=&quot;post&quot; name=&quot;main1&quot;> <input name=&quot;file&quot; type=&quot;file&quot; size=&quot;50&quot;> <INPUT type=&quot;text&quot; id=text1 name=text1><INPUT type=&quot;text&quot; id=text2 name=text2> <input name=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Upload&quot;> </li>  Copy the following code to an editor such as Notepad or Visual Interdev, and then save it as UploadFile.asp : <%@ Language=VBScript %> <% '//////////////////////////////////////////////////////////////////////////////////  '//  ASPFileUpload.File API '//   '//  Properties '//    FileName '//      - Read/Write '//      - The file will be saved with this file name. '//      - This property can only be set before calling Upload. '//      - If no value is specified, the original file name '//      - in the HTTP post will be used. '//      '//     OverWrite '//      - Read/Write '//      - This property can only be set before calling Upload. '//      - If set to false and if the destination file exists, an error '//      - is raised. The default value is False. '//      '//     Target '//      - Read/Write '//      - The file will be written to this folder. '//      - This property can only be set before calling Upload. '//      - There is no default value for this property and it is required. '//        '//      Form '//       - ReadOnly '//       - Scripting.Dictionary object '//       - Can access a specific item by using aspfileupload.Form(&quot;item&quot;). '//       - Acts like the asp form collection. '//       - Can enumerate all values in a collection with for each. '//       - Only filled after the Upload method is called. '//          '//  Methods '//    Upload '//      - This method parses the HTTP Post and writes the file. '//   '//  Other '//   - ASPFileUpload requires COM+ '//   - Any call to the Request.Form collection will cause the Upload '//     method to fail as the method references the Binary contents of the '//     Request object through the Request.BinaryRead method. '//   - Also, if you access a variable in the Request collection without '//     specifying the subcollection that it belongs to, the Request.Form collection '//     may be searched. This causes an error in the Upload method. '//       '//////////////////////////////////////////////////////////////////////////////////  Dim strMsg 'As String ' On Error Resume Next dim fuFile set fuFile = server.CreateObject(&quot;aspFileupload.file&quot;) 'Set the destination folder. fuFile.Target = &quot;C:\TEMP\AspFileUpload\&quot; fuFile.Upload If Err.number = 0 Then strMsg = fuFile.FileName & &quot; was uploaded successfully.&quot; Else strMsg = &quot;An error occurred when uploading your file: &quot; & Err.Description End If for each o in fuFile.Form Response.Write o & &quot;<BR>&quot; next Response.Write fuFile.Form.item(&quot;text1&quot;) & &quot; :  &quot; & fuFile.Form.item(&quot;text2&quot;) ' Response.Write Request.Form(&quot;test&quot;) set fufile = nothing %> <%=strMsg%> </li></ol>

back to the top

Set Up the Server
<ol> Create a folder on the Web server that will receive the uploaded files, such as C:\TEMP\AspFileUpload .</li> Copy the ASPFileUpload.dll file to the Web server, and then register it by using the following command at the command prompt:

regsvr32 \ASPFileUpload.dll

</li> Apply file permissions (Write access) for the users who you want to be able to upload the files.</li> <li>Click Start, point to Settings, and then click Control Panel.</li> <li>In Control Panel, click Administrative Tools, and then click Component Services to open Component Services in the Microsoft Management Console (MMC).</li> <li>Expand the Component Services node, the Computers node, the My Computer node, and the COM+ Applications node.</li> <li>Right-click the node, point to New, and then click Application.</li> <li>In the Install or Create a New Application dialog box, click Create an empty application, name the application, make sure that you click to select Server application, and then click Next.</li> <li>In the Set Application Identity dialog box, click This User, and then type the credentials for the appropriate user account. The user account must have Write access to the folder that will receive the uploaded file.</li> <li>Click Finish.</li> <li>Expand the node that you have just created for this application.</li> <li>Right-click the nod, point to New, and then click Component.</li> <li>Click Install new components, and locate the folder where you have saved and registered the .dll file, click the file, click Next, and then click Finish.</li> <li>Copy the Postfile.asp file and the Uploadfile.asp file to your Web root folder. By default, the Web root folder is C:\Inetpub\Wwwroot.</li> <li> Edit the target folder of Uploadfile.asp to reflect the folder that you created in step 1. The target folder assignment is located in the following line of code: fuFile.Target = &quot;C:\TEMP\AspFileUpload\&quot; </li></ol>

back to the top

Upload a File
<ol> <li>In a Web browser, open the Postfile.asp page at the following URL:

http:// /Postfile.asp

</li> <li>Select a file that you want to upload, and then click Upload.</li> <li>Check your upload folder. The file that you uploaded appears in this folder.</li></ol>

back to the top

Troubleshooting

 * If you do not type a file name, and if you try to submit the Postfile.asp page, you receive a generic, server-side error message. You may want to modify the code to provide a more friendly error message on either the client side or on the server side.
 * If you require high volume upload capacity, Microsoft recommends that you buy or build a compiled, multithreaded component that can more efficiently handle the load than this Visual Basic component.
 * A potential security risk exists whenever you allow users to upload files to your Web server. This is especially true if your server is on the Internet, and if you allow anonymous uploads. You must correctly configure Windows permissions and IIS user authentication to make sure that you give users only the access that they require. This is important so that you do not allow users a way to gain access by bypassing the security controls of your system.

back to the top

Additional query words: back door

Keywords: kbhowto kbscript kbwebserver kbserver kbcodesnippet kbguidelines kbaspobj kbfile kbsecurity kbsetup kbsample kbconfig kbfso kbdeployment KB299692

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.