static void UpdateTopLevelNodes(OIMNTFS.FilesystemsRow fileSystem) { DirectoryInfo dInfo = null; DirectorySecurity dSecurity = null; string[] topLevelNodePaths = (string[])null; Int64 filesystemID = fileSystem.ID; try { topLevelNodePaths = Directory.GetDirectories(fileSystem.DriveRoot, "*", SearchOption.TopDirectoryOnly); } catch (Exception e) { Console.WriteLine("Directories in {0} cannot be read.", fileSystem.DriveRoot); Console.WriteLine("{0}", e.Message); return; } foreach (string topLevelNodePath in topLevelNodePaths) { if (excludeNodes.Select("'" + topLevelNodePath + "' LIKE excludeNode").Length > 0) { continue; } try { dInfo = new DirectoryInfo(topLevelNodePath); dSecurity = dInfo.GetAccessControl(); } catch (Exception e) { Console.WriteLine("Directory info in {0} cannot be read.", topLevelNodePath); Console.WriteLine("{0}", e.Message); continue; } DateTime lastWrite = dInfo.LastWriteTimeUtc; DateTime lastAccess = dInfo.LastAccessTimeUtc; string ownerSID = null; string owner = null; try { ownerSID = dSecurity.GetOwner(typeof(System.Security.Principal.SecurityIdentifier)).Value; owner = ad.getObjectName(ownerSID); } catch (Exception e) { Console.WriteLine("Unable to read owner of {0}", topLevelNodePath); Console.WriteLine(e.Message); } Boolean isProtected = dSecurity.AreAccessRulesProtected; if (topLevelNodes.Select("FullPath = '" + dInfo.FullName + "'").Length == 0) { Console.WriteLine("Found new node '{0}'", dInfo.FullName); OIMNTFS.TopLevelNodesRow newTopLevelNode = topLevelNodes.NewTopLevelNodesRow(); newTopLevelNode.FilesystemID = filesystemID; newTopLevelNode.ScanDepth = fileSystem.Depth; newTopLevelNode.FullPath = dInfo.FullName; newTopLevelNode.Name = dInfo.Name; newTopLevelNode.LastAccessUTC = dInfo.LastAccessTimeUtc; newTopLevelNode.LastWriteUTC = dInfo.LastWriteTimeUtc; newTopLevelNode.LastScanned = DateTime.MinValue; newTopLevelNode.FirstSeen = DateTime.UtcNow; newTopLevelNode.DataOwner = owner; newTopLevelNode.isProtected = isProtected; topLevelNodes.AddTopLevelNodesRow(newTopLevelNode); } } if (writeDatabase) { topLevelNodesTable.Update(topLevelNodes); } }
private void FullScan() { eventLog.Buffer("Refreshing file systems table."); fileSystemsTable.ClearBeforeFill = true; fileSystemsTable.Fill(fileSystems); eventLog.Buffer("{0} file systems read.", fileSystems.Count); eventLog.Buffer("Refreshing exclude nodes table."); excludeNodesTable.ClearBeforeFill = true; excludeNodesTable.Fill(excludeNodes); eventLog.Buffer("{0} exclude nodes read.", excludeNodes.Count); foreach (OIMNTFS.FilesystemsRow fileSystem in fileSystems.Rows) { eventLog.Buffer("Reading file system {0}", fileSystem.DriveRoot); service.networkDrive.LocalDrive = fileSystem.DriveRoot.Substring(0, 2); service.networkDrive.Persistent = false; service.networkDrive.SaveCredentials = false; service.networkDrive.Force = true; service.networkDrive.ShareName = "\\\\" + fileSystem.ProviderIP + "\\" + fileSystem.Share; eventLog.Buffer("Mapping drive {0} to {1}", service.networkDrive.LocalDrive, service.networkDrive.ShareName); try { switch (fileSystem.Type) { case 0: service.networkDrive.MapDrive(); break; case 1: service.networkDrive.MapDrive(fileSystem.User, fileSystem.Password); break; default: service.networkDrive.MapDrive(fileSystem.User, fileSystem.Password); break; } } catch (Exception e) { eventLog.Buffer("unable to map drive {0} to {1}", service.networkDrive.LocalDrive, service.networkDrive.ShareName); eventLog.Buffer("{0}", e.ToString()); continue; } eventLog.Buffer("Updating top level folders of {0}...", fileSystem.DriveRoot); DirectoryInfo dInfo = null; DirectorySecurity dSecurity = null; string[] topLevelNodePaths = (string[])null; Int64 filesystemID = fileSystem.ID; try { topLevelNodePaths = Directory.GetDirectories(fileSystem.DriveRoot, "*", SearchOption.TopDirectoryOnly); } catch (Exception e) { eventLog.Buffer("Directories in {0} cannot be read.", fileSystem.DriveRoot); eventLog.Buffer("{0}", e.Message); continue; } foreach (string topLevelNodePath in topLevelNodePaths) { if (excludeNodes.Select("'" + topLevelNodePath + "' LIKE excludeNode").Length > 0) { continue; } try { dInfo = new DirectoryInfo(topLevelNodePath); dSecurity = dInfo.GetAccessControl(); } catch (Exception e) { eventLog.Buffer("Directory info in {0} cannot be read.", topLevelNodePath); eventLog.Buffer("{0}", e.Message); continue; } DateTime lastWrite = dInfo.LastWriteTimeUtc; DateTime lastAccess = dInfo.LastAccessTimeUtc; string ownerSID = null; string owner = null; try { ownerSID = dSecurity.GetOwner(typeof(System.Security.Principal.SecurityIdentifier)).Value; owner = service.adCache.getObjectName(ownerSID); } catch (Exception e) { eventLog.Buffer("Unable to read owner of {0}", topLevelNodePath); eventLog.Buffer(e.Message); } Boolean isProtected = dSecurity.AreAccessRulesProtected; if (topLevelNodes.Select("FullPath = '" + dInfo.FullName + "'").Length == 0) { eventLog.Buffer("Found new node '{0}'", dInfo.FullName); OIMNTFS.TopLevelNodesRow newTopLevelNode = topLevelNodes.NewTopLevelNodesRow(); newTopLevelNode.FilesystemID = filesystemID; newTopLevelNode.ScanDepth = fileSystem.Depth; newTopLevelNode.FullPath = dInfo.FullName; newTopLevelNode.Name = dInfo.Name; newTopLevelNode.LastAccessUTC = dInfo.LastAccessTimeUtc; newTopLevelNode.LastWriteUTC = dInfo.LastWriteTimeUtc; newTopLevelNode.LastScanned = DateTime.MinValue; newTopLevelNode.FirstSeen = DateTime.UtcNow; newTopLevelNode.DataOwner = owner; newTopLevelNode.isProtected = isProtected; topLevelNodes.AddTopLevelNodesRow(newTopLevelNode); } } topLevelNodesTable.Update(topLevelNodes); } // now start to process all top level nodes foreach (OIMNTFS.TopLevelNodesRow topLevelNode in topLevelNodes.OrderBy(n => n.LastScanned)) { eventLog.Buffer("Scanning {0} down to level {1}...", topLevelNode.FullPath, topLevelNode.ScanDepth); try { // if scanner is working on same top level node, wait for it to complete while (service.scanner.CurrentTopLevelNode() == topLevelNode.ID) { this.eventLog.Write("FullScan is waiting for single scan below {0} to complete.", topLevelNode.FullPath); System.Threading.Thread.Sleep(5000); // busy wait :-( } _CurrentTopLevelNode = topLevelNode.ID; start = DateTime.Now; _FolderCounter = 0; _EntitlementCounter = 0; _ProtectedCounter = 0; ProcessNode(topLevelNode.FullPath, 1, topLevelNode.ScanDepth, topLevelNode.ID, 0); eventLog.Buffer("Done."); eventLog.Buffer("Updating database..."); try { // first delete old values eventLog.Buffer("Deleting old scan information for {0}...", topLevelNode.FullPath); SqlCommand delnodes = conn.CreateCommand(); delnodes.CommandText = string.Format("DELETE FROM [OIMNTFS].[dbo].[Nodes] WHERE TopLevelNodeID = {0}", topLevelNode.ID); delnodes.ExecuteNonQuery(); // update last scanned timestamp (topLevelNodes.FindByID(topLevelNode.ID)).LastScanned = DateTime.Now; // now update (insert) nodes processed topLevelNodesTable.Update(topLevelNodes); } catch (Exception e) { eventLog.Buffer("Failed to update last scanned timestamp for {0}", topLevelNode.FullPath); eventLog.Buffer(e.Message); } eventLog.Buffer("{0} completed on {1:hh:mm:ss}.\n{2} folders read ({3:0.0} folders per second)\n", topLevelNode.FullPath, DateTime.Now, _FolderCounter, _FolderCounter / (DateTime.Now - start).TotalSeconds, _FolderCounter); // Update last access and last write timestamp on TopLevelFolders string cmdtext = @" WITH NodesMax AS ( SELECT TopLevelNodes.ID, maxlastaccess = MAX(LastAccess), maxlastwrite = MAX(LastWrite) FROM TopLevelNodes JOIN Nodes ON Nodes.TopLevelNodeID = TopLevelNodes.ID GROUP BY TopLevelNodes.ID ) UPDATE TopLevelNodes SET LastTreeAccessUTC = NodesMax.maxlastaccess, LastTreeWriteUTC = NodesMax.maxlastwrite FROM ToplevelNodes JOIN NodesMax ON NodesMax.ID = TopLevelNodes.ID"; (new SqlCommand(cmdtext, conn)).ExecuteNonQuery(); eventLog.Flush(); } catch (Exception e) { this.eventLog.Write("Exception during scan below {0}: {1}", topLevelNode.FullPath, e.Message); eventLog.Buffer("Exception during scan below {0}: {1}", topLevelNode.FullPath, e.Message); } finally { _CurrentTopLevelNode = 0; eventLog.Flush(); } } }