08-18-04 10:57 PM
A long while back, I wrote this piece of code you may find useful;
It was supposed to provide a custom "FileSystemObject" implementation which
would not allow users to break out of their root directory in a web hosting
environment.
It's been so long I can't really recall how I did things exactly, but if I
had to guess:
-Disable native FileSystemObject support [through the registry, I think?
]
-Then register the .NET assembly with IIS through the command line ["reg
asm
/tlb /codebase [assemblypath]" maybe ?]
I had imported the ASPTypeLibrary and Scripting dll's, which must be
referenced when compiling the project.
I also believe the entire FileSystemObject API is implemented below in the
encapsulating classes.
your users would then instantiate the "FileSystemObject" with a:
Server.CreateObject("Custom.FileSystemObject") instead of
...("Scripting.FileSystemObject")
If you find it helpful, do with it what you please
using System;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;
using ASPTypeLibrary; // COM Interoped ASP Classes.
using Scripting; // COM Interoped Scripting Classes.
namespace Custom {
/**
* FileSystemObject - File Implementation.
*/
public sealed class File : Scripting.File {
internal FileSystemObject fso;
internal Scripting.File file;
public File(FileSystemObject fso, Scripting.File file) {
this.fso = fso;
this.file = file;
}
public FileAttribute Attributes {
get {
return file.Attributes;
} set {
file.Attributes = value;
}
}
public DateTime DateCreated {
get {
return file.DateCreated;
}
}
public DateTime DateLastAccessed {
get {
return file.DateLastAccessed;
}
}
public DateTime DateLastModified {
get {
return file.DateLastModified;
}
}
public Drive Drive {
get {
throw new NotSupportedException();
}
}
public string Name {
get {
return file.Name;
} set {
file.Name = value;
}
}
public Scripting.Folder ParentFolder {
get {
return new Folder(fso, file.ParentFolder);
}
}
public string Path {
get {
return file.Path;
}
}
public string ShortName {
get {
return file.ShortName;
}
}
public string ShortPath {
get {
return file.ShortPath;
}
}
public object Size {
get {
return file.Size;
}
}
public string Type {
get {
return file.Type;
}
}
/* Added for backwards compatibility. */
public void Copy(string destination) {
fso.CopyFile(Path, destination);
}
public void Copy(string destination, bool overwrite) {
fso.CopyFile(Path, destination, overwrite);
}
/* Added for backwards compatibility. */
public void Delete() {
fso.DeleteFile(Path);
}
public void Delete(bool force) {
fso.DeleteFile(Path, force);
}
public void Move(string destination) {
fso.MoveFile(Path, destination);
}
/* Added for backwards compatibility. */
public TextStream OpenAsTextStream() {
return fso.OpenTextFile(Path);
}
/* Added for backwards compatibility. */
public TextStream OpenAsTextStream(short mode) {
return fso.OpenTextFile(Path, mode);
}
/* Added for backwards compatibility. */
public TextStream OpenAsTextStream(short mode, short format) {
return fso.OpenTextFile(Path, mode, false, format);
}
public TextStream OpenAsTextStream(IOMode mode, Tristate format) {
return fso.OpenTextFile(Path, mode, false, format);
}
}
/**
* FileSystemObject - Files Implementation.
*/
public sealed class Files : Scripting.Files {
internal FileSystemObject fso;
internal Scripting.Files files;
public Files(FileSystemObject fso, Scripting.Files files) {
this.fso = fso;
this.files = files;
}
public int Count {
get {
return files.Count;
}
}
public IEnumerator GetEnumerator() {
return files.GetEnumerator();
}
public Scripting.File this[object id] {
get {
return new File(fso, files[id]);
}
}
}
/**
* FileSystemObject - Folder Implementation.
*/
public sealed class Folder : Scripting.Folder {
internal FileSystemObject fso;
internal Scripting.Folder dir;
public Folder(FileSystemObject fso, Scripting.Folder dir) {
this.fso = fso;
this.dir = dir;
}
public FileAttribute Attributes {
get {
return dir.Attributes;
} set {
dir.Attributes = value;
}
}
public DateTime DateCreated {
get {
return dir.DateCreated;
}
}
public DateTime DateLastAccessed {
get {
return dir.DateLastAccessed;
}
}
public DateTime DateLastModified {
get {
return dir.DateLastModified;
}
}
public Drive Drive {
get {
throw new NotSupportedException();
}
}
public Scripting.Files Files {
get {
return new Files(fso, dir.Files);
}
}
public bool IsRootFolder {
get {
return dir.IsRootFolder;
}
}
public string Name {
get {
return dir.Name;
} set {
dir.Name = value;
}
}
public Scripting.Folder ParentFolder {
get {
Folder folder = null;
try {
DirectoryInfo parent = new DirectoryInfo(Path);
parent = new
DirectoryInfo(fso.GetDirectoryPath(parent.Parent.FullName, true));
folder = new Folder(fso, dir.ParentFolder);
} catch {
folder = null;
}
return folder;
}
}
public string Path {
get {
return dir.Path;
}
}
public string ShortName {
get {
return dir.ShortName;
}
}
public string ShortPath {
get {
return dir.ShortPath;
}
}
public object Size {
get {
return dir.Size;
}
}
public Scripting.Folders SubFolders {
get {
return new Folders(fso, dir.SubFolders);
}
}
public string Type {
get {
return dir.Type;
}
}
/* Added for backwards compatibility. */
public void Copy(string destination) {
fso.CopyFolder(Path, destination);
}
public void Copy(string destination, bool overwrite) {
fso.CopyFolder(Path, destination, overwrite);
}
/* Added for backwards compatibility. */
public void Delete() {
fso.DeleteFolder(Path);
}
public void Delete(bool force) {
fso.DeleteFolder(Path, force);
}
public void Move(string destination) {
fso.MoveFolder(Path, destination);
}
/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename) {
return fso.CreateTextFile(System.IO.Path.Combine(Path, filename));
}
/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename, bool overwrite) {
return fso.CreateTextFile(System.IO.Path.Combine(Path, filename),
overwrite);
}
public TextStream CreateTextFile(string filename, bool overwrite, bool
unicode) {
//FileInfo file = new FileInfo(fso.GetFilePath(filename));
//return dir.CreateTextFile(file.FullName, overwrite, unicode);
return fso.CreateTextFile(System.IO.Path.Combine(Path, filename),
overwrite, unicode);
}
}
/**
* FileSystemObject - Folders Implementation.
*/
public sealed class Folders : Scripting.Folders {
internal FileSystemObject fso;
internal Scripting.Folders folders;
public Folders(FileSystemObject fso, Scripting.Folders folders) {
this.fso = fso;
this.folders = folders;
}
public Scripting.Folder Add(string filename) {
throw new NotSupportedException();
}
public int Count {
get {
return folders.Count;
}
}
public IEnumerator GetEnumerator() {
return folders.GetEnumerator();
}
public Scripting.Folder this[object id] {
get {
return new Folder(fso, folders[id]);
}
}
}
/**
* FileSystemObject - FileSystemObject Implementation.
*/
public sealed class FileSystemObject : Scripting.FileSystemObject {
private Scripting.FileSystemObject FSO;
private ScriptingContext Context;
private Request Request;
private Server Server;
private DirectoryInfo RootDirectory;
public FileSystemObject() : base() {
Request = null;
Context = null;
Server = null;
RootDirectory = null;
// Initialize internal Scripting.FileSystemObject.
FSO = new Scripting.FileSystemObject();
}
/**
* Entrypoint function called by IIS with the current ScriptingContext.
*/
public void onStartPage(ScriptingContext Context) {
try {
this.Context = Context;
if(Context == null) {
throw new ArgumentNullException("Context");
}
this.Request = Context.Request; //
(RequestClass)Marshal.CreateWrapperOfType(Request, typeof(RequestClass));
if(Request == null) {
throw new ArgumentNullException("Request");
}
this.Server = Context.Server;
if(Server == null) {
throw new ArgumentNullException("Server");
}
string path = String.Empty;
IStringList list = (IStringList)Request.ServerVariables["URL"];
if(list != null && list.Count == 1) {
path = list[1].ToString(); // Reminder: VB/ASP Arrays are not
zero-based.
} else {
throw new ArgumentNullException("List");
}
if(path == null || path.Length == 0) {
throw new ArgumentNullException("Path");
}
while(path.StartsWith("/")) {
path = path.Substring(1, path.Length - 1);
}
if(path.IndexOf("/") <= 0) {
throw new Exception();
}
path = "/" + path.Substring(0, path.IndexOf("/")) + "/";
RootDirectory = new DirectoryInfo(Server.MapPath(path));
if(RootDirectory == null || !(RootDirectory.Exists)) {
throw new ArgumentNullException("RootDirectory");
}
} catch {
throw new Exception("Unable to initialize Custom.FileSystemObject");
}
}
public Drives Drives {
get {
throw new NotSupportedException();
}
}
public string BuildPath(string path1, string path2) {
return FSO.BuildPath(path1, path2);
}
/* Added for backwards compatibility. */
public void CopyFile(string source, string destination) {
CopyFile(source, destination, true);
}
public void CopyFile(string source, string destination, bool overwrite)
{
CheckInitialized();
FileInfo srcFile = new FileInfo(GetFilePath(source, true));
srcFile.CopyTo(destination, overwrite);
}
/* Added for backwards compatibility. */
public void CopyFolder(string source, string destination) {
CopyFolder(source, destination, true);
}
public void CopyFolder(string source, string destination, bool
overwrite) {
CheckInitialized();
DirectoryInfo srcDir = new DirectoryInfo(GetDirectoryPath(source,
true));
InternalDirectoryCopy(srcDir, GetDirectoryPath(destination),
overwrite);
}
public Scripting.Folder CreateFolder(string filename) {
CheckInitialized();
DirectoryInfo dir = new DirectoryInfo(GetDirectoryPath(filename)
);
return new Folder(this, FSO.CreateFolder(dir.FullName));
}
/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename) {
return CreateTextFile(filename, false);
}
/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename, bool overwrite) {
return CreateTextFile(filename, overwrite, false);
}
public TextStream CreateTextFile(string filename, bool overwrite, bool
unicode) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename));
return FSO.CreateTextFile(file.FullName, overwrite, unicode);
}
/* Added for backwards compatibility. */
public void DeleteFile(string filename) {
DeleteFile(filename, true);
}
public void DeleteFile(string filename, bool force) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename, true));
file.Delete();
}
/* Added for backwards compatibility. */
public void DeleteFolder(string filename) {
DeleteFolder(filename, true);
}
public void DeleteFolder(string filename, bool force) {
CheckInitialized();
DirectoryInfo dir = new DirectoryInfo(GetDirectoryPath(filename,
true));
dir.Delete(true);
}
public bool DriveExists(string path) {
throw new NotSupportedException();
}
public bool FileExists(string filename) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename));
return file.Exists;
}
public bool FolderExists(string filename) {
CheckInitialized();
DirectoryInfo dir = new DirectoryInfo(GetDirectoryPath(filename)
);
return dir.Exists;
}
public string GetAbsolutePathName(string path) {
return FSO.GetAbsolutePathName(path);
}
public string GetBaseName(string path) {
return FSO.GetBaseName(path);
}
public Drive GetDrive(string path) {
throw new NotSupportedException();
}
public string GetDriveName(string path) {
throw new NotSupportedException();
}
public string GetExtensionName(string path) {
return FSO.GetExtensionName(path);
}
public Scripting.File GetFile(string filename) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename, true));
return new File(this, FSO.GetFile(file.FullName));
}
public string GetFileVersion(string path) {
return FSO.GetFileVersion(path);
}
public string GetFileName(string path) {
return FSO.GetFileName(path);
}
public Scripting.Folder GetFolder(string filename) {
CheckInitialized();
DirectoryInfo dir = new DirectoryInfo(GetDirectoryPath(filename,
true));
return new Folder(this, FSO.GetFolder(dir.FullName));
}
public string GetParentFolderName(string path) {
return FSO.GetParentFolderName(path);
}
public Scripting.Folder GetSpecialFolder(SpecialFolderConst
specialFolder) {
throw new NotSupportedException();
}
public TextStream GetStandardStream(StandardStreamTypes streamType, bool
unicode) {
throw new NotSupportedException();
}
public string GetTempName() {
return FSO.GetTempName();
}
public void MoveFile(string source, string destination) {
CheckInitialized();
FileInfo srcFile = new FileInfo(GetFilePath(source, true));
srcFile.MoveTo(GetFilePath(destination));
}
public void MoveFolder(string source, string destination) {
CheckInitialized();
DirectoryInfo srcDir = new DirectoryInfo(GetDirectoryPath(source,
true));
srcDir.MoveTo(GetDirectoryPath(destination));
}
/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename) {
return OpenTextFile(filename, 1);
}
/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename, short mode) {
return OpenTextFile(filename, mode, false);
}
/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename, short mode, bool create)
{
return OpenTextFile(filename, mode, create, 0);
}
/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename, short smode, bool
create, short sformat) {
IOMode mode = IOMode.ForReading;
Tristate format = Tristate.TristateFalse;
if(smode == 1) {
mode = IOMode.ForReading;
} else if(smode == 2) {
mode = IOMode.ForWriting;
} else if(smode == 8) {
mode = IOMode.ForAppending;
}
if(sformat == -2) {
format = Tristate.TristateUseDefault;
} else if(sformat == -1) {
format = Tristate.TristateTrue;
} else if(sformat == 0) {
format = Tristate.TristateFalse;
}
return OpenTextFile(filename, mode, create, format);
}
public TextStream OpenTextFile(string filename, IOMode mode, bool
create, Tristate format) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename));
return FSO.OpenTextFile(file.FullName, mode, create, format);
}
// Internal Operations.
internal string GetFilePath(string relpath) {
return GetFilePath(relpath, false);
}
internal string GetFilePath(string relpath, bool checkExists) {
CheckInitialized();
string path = null;
try {
FileInfo file = (Path.IsPathRooted(relpath)) ? new FileInfo(relpath)
: new FileInfo(Path.Combine(RootDirectory.FullName, relpath));
if(file == null || (checkExists && !(file.Exists))) {
throw new ArgumentNullException("File");
}
if(!(file.Directory.FullName.StartsWith(RootDirectory.FullName))) {
throw new Exception("Error: Hacking attempt");
}
path = file.FullName;
} catch {
throw new Exception("Custom.FileSystemObject Path Error");
}
return path;
}
internal string GetDirectoryPath(string relpath) {
return GetDirectoryPath(relpath, false);
}
internal string GetDirectoryPath(string relpath, bool checkExists) {
CheckInitialized();
string path = null;
try {
DirectoryInfo dir = (Path.IsPathRooted(relpath)) ? new
DirectoryInfo(relpath) : new
DirectoryInfo(Path.Combine(RootDirectory.FullName, relpath));
if(dir == null || (checkExists && !(dir.Exists))) {
throw new ArgumentNullException("Dir");
}
if(!(dir.FullName.StartsWith(RootDirectory.FullName))) {
throw new Exception("Error: Hacking attempt");
}
path = dir.FullName;
} catch {
throw new Exception("Custom.FileSystemObject Path Error");
}
return path;
}
// Private Helper Operations.
private void CheckInitialized() {
if(!((FSO != null && Request != null && Context != null && Server !=
null && RootDirectory != null && RootDirectory.Exists))) {
throw new Exception("Custom.FileSystemObject not initialized.");
}
}
private void InternalDirectoryCopy(DirectoryInfo source, string
destination, bool overwrite) {
if(source == null) {
return;
}
foreach(FileSystemInfo fso in source.GetFileSystemInfos()) {
string destName = Path.Combine(source.FullName, fso.Name);
if(fso is FileInfo) {
System.IO.File.Copy(fso.FullName, destName, overwrite);
} else if(fso is DirectoryInfo) {
Directory.CreateDirectory(destName);
InternalDirectoryCopy((DirectoryInfo)fso
, destName, overwrite);
}
}
}
}
}
[ Post a follow-up to this message ]
|