/// <summary> /// Update or add an entry for a file in the shared files /// database. /// </summary> /// <param name="info">FileInfo for the file to process.</param> private void ProcessFile(FileInfo info) { FilesDataSet.SharesDataTable shares = files.Shares; Action action; string hash; // See if this file is already in the database. FilesDataSet.SharesRow row = shares.FindByFullName(info.FullName); if (row != null) { // The file was found, so keep this row. row.Keep = true; // Update the hash if this file was modified since we // last saw it. if (row.LastModified < info.LastWriteTime) { hash = ComputeHashForFile(info.FullName); // Delete the row if this file is now a duplicate. if (shares.Select("Hash = '" + hash + "'").Length > 0) { row.Delete(); action = Action.DuplicateDeleted; } else { // File modified, update the hash. row.Hash = hash; action = Action.HashUpdated; } } else { // This file was already in the database and // has not been modified. return; } } else { hash = ComputeHashForFile(info.FullName); // Don't add this file if this is a duplicate. if (shares.Select("Hash = '" + hash + "'").Length > 0) { action = Action.DuplicateIgnored; } else { // This is a new file, add it. shares.AddSharesRow(info.FullName, hash, info.LastWriteTime, info.Length, true); action = Action.Added; } } OnFileUpdated(new FileUpdatedEventArgs(info, action)); }
void IHttpWorkerRequestHandler.ProcessRequest(HttpWorkerRequest wr) { string hash = wr.GetUriPath(); if (hash.StartsWith("/")) { hash = hash.Substring(1); } string query = String.Format("Hash = '{0}'", hash); FilesDataSet.SharesRow[] rows; lock (shares) { rows = shares.Select(query) as FilesDataSet.SharesRow[]; } if (rows.Length == 1) { string fullName = rows[0].FullName; string name = fullName.Substring(fullName.LastIndexOf('\\') + 1); long offset = 0; long length = rows[0].Size; string range = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderRange); if (range != null && range.Length > 0) { int rangeStart = range.IndexOf("bytes="); int rangeEnd = range.IndexOf('-'); if (rangeStart != -1 && rangeEnd != -1 && rangeEnd - rangeStart > 1) { rangeStart += 6; offset = Int64.Parse(range.Substring( rangeStart, rangeEnd - rangeStart)); } } SendFile(wr, fullName, name, offset, length - offset); } else { string message = "The requested file was not found."; byte[] bytes = Encoding.UTF8.GetBytes(message); wr.SendStatus(404, HttpWorkerRequest.GetStatusDescription(404)); wr.SendUnknownResponseHeader("Accept-Ranges", "bytes"); wr.SendUnknownResponseHeader("Content-Type", "text/plain"); wr.SendResponseFromMemory(bytes, bytes.Length); wr.FlushResponse(true); wr.EndOfRequest(); } }
private void StartScan(object state) { string sharedFolder; bool subfolders; lock (Properties.Settings.Default) { sharedFolder = Properties.Settings.Default.SharedFolder; subfolders = Properties.Settings.Default.IncludeSubfolders; } // If the share directory does not exist, silently get out. if (!Directory.Exists(sharedFolder)) { return; } FilesDataSet.SharesDataTable shares = files.Shares; // Set the Keep column of all files to false. // Whenever we encounter a file, the Keep column will // be set to true. This way, deleted files will be removed // from the database. foreach (FilesDataSet.SharesRow row in shares.Rows) { row.Keep = false; } ScanFolder(new DirectoryInfo(sharedFolder), subfolders); // Delete rows for all files that do not exist anymore, // or are not shared anymore. DataRow[] rows = shares.Select("Keep = false"); foreach (DataRow row in rows) { row.Delete(); } shares.AcceptChanges(); OnScanComplete(new EventArgs()); }