Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 15, 2014 errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Hi, I am trying to make a little application to revert the effect of some viruses on USB memories, and running it from Windows encountered some exceptions that IMHO should not have happened. Maybe I am missing something. Can you please check the commented blocks for errors? Also, is there a way from Linux to remove attributes readonly, system, hidden ? Regards, Hugo import std.stdio; import std.path; import std.regex; import std.file; import std.string; static string info = "CureUSB 0.3 (2014-01-14)"; static string str_moved = "Moved"; static string str_deleted = "Deleted"; static string str_finished = "Done"; static string str_setattrib = "Attributes set"; static string str_safename = "SafeToDelete"; // Expression to match directories with blanks for name static auto re = regex(`^\s+$`); version(Windows) { import core.sys.windows.windows; extern(Windows) uint SetFileAttributesA(LPCSTR, DWORD); } int main() { string ExePath = thisExePath(); string SearchPath = rootName(ExePath); string BlankDirToDelete; version(Windows) SetConsoleOutputCP(65001); writefln(info); foreach(DirEntry d; dirEntries(SearchPath, SpanMode.shallow)) { auto m = matchFirst(baseName(d.name), re); if (m.captures.length > 0) { if (isDir(d.name)) { foreach(DirEntry f; dirEntries(d.name, SpanMode.shallow)) { string origname = buildPath(SearchPath, baseName(f.name)); rename(f.name, origname); writefln(`%s "%s"`, str_moved, origname); } BlankDirToDelete = d.name; } break; } } // The following block does not work; supposedly the process does not have // access to the directory because it is being used by another process, // which does not seem to be the case. Uncomment to try /* if (exists(BlankDirToDelete)) try { string SafeToBeDeleted = buildPath(SearchPath, str_safename) rename(BlankDirToDelete, SafeToBeDeleted); remove(SafeToBeDeleted); } catch (FileException e) writeln(e.msg); */ foreach(DirEntry d; dirEntries(SearchPath, SpanMode.shallow)) { if (d.name != ExePath) { string bname = baseName(d.name); version(Windows) { if ( (bname != "RECYCLER") && (bname != "$Recycle.bin") && (bname != "System Volume Information") && (bname != "Recovery") && (bname != "MSOCache") ) SetFileAttributesA(toStringz(d.name), FILE_ATTRIBUTE_NORMAL + FILE_ATTRIBUTE_ARCHIVE); } // The following block gives a FileException, claiming that the specified file // could not befound. Uncomment to try /* string exten = extension(d.name); if (exten.length > 0) { // writefln(`"%s" "%s"`, d.name, extension(d.name)); //debug line if ( (exten == ".exe") || (exten == ".lnk") || (exten == ".scr") || (exten == ".cpl") || (exten == ".hta") || (exten == ".com") || (exten == ".bat") || (exten == ".vb") || (exten == ".vbs") ) if (isDir(buildPath(SearchPath, stripExtension(baseName(d.name))))) { remove(d.name); writefln(`%s "%s"`, str_deleted, d.name); } } */ } } writefln("%s", str_setattrib); writefln("%s.", str_finished); return 0; } |
January 15, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hugo Florentino | On 2014-01-15 11:33, Hugo Florentino wrote: > Hi, > > I am trying to make a little application to revert the effect of some > viruses on USB memories, and running it from Windows encountered some > exceptions that IMHO should not have happened. > Maybe I am missing something. Can you please check the commented blocks > for errors? > > Also, is there a way from Linux to remove attributes readonly, system, > hidden ? As of 2.065 (not release yet) you can set file attributes using std.file.setAttributes [1]. On Linux, hidden files are all files where the filename starts with a dot. To make it visible you need to rename the file. As far as I know, Linux doesn't have any form of system attribute. [1] https://github.com/D-Programming-Language/phobos/commit/5ab8dae665c27ed45eced244720e23e53ef23457 -- /Jacob Carlborg |
January 15, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Wed, 15 Jan 2014 13:41:50 +0100, Jacob Carlborg wrote:
> ... On Linux, hidden files are all files where
> the filename starts with a dot. To make it visible you need to rename
> the file. As far as I know, Linux doesn't have any form of system
> attribute.
I am aware of this. However, FAT32 and NTFS (through ntfs-3g) and even ExFAT (I do not remember now the name of the project) are supported by Linux, so there should be a way to alter file structure so as to change attributes even if the OS does not natively provide a function for this (why should a user working in Linux be forced to reboot in Windows not even to run an unported application but just to change file attributes in a filesystem the OS supports)?
Has anyone attempted it from D?
|
January 16, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hugo Florentino | Probably because you use ansi api: if filename contains non-english character, there could be a problem. A filesystem support is primarily for storing files, attributes can be safely ignored. |
January 16, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Thu, 16 Jan 2014 15:41:06 +0000, Kagamin wrote:
> Probably because you use ansi api: if filename contains non-english
> character, there could be a problem.
>
> A filesystem support is primarily for storing files, attributes can
> be safely ignored.
Hmm... that may be true for Linux filesystems, but not necessarily for filesystems used by Windows, where attributes do matter.
Probably the majority of people here works from Linux and maybe most have the good fortune that the rest of the users in their organization either works in Linux too, or are computer literate persons. However where I work all users work in Windows (there is a specific application for the management of music rights which has not been ported to Linux AFAIK) and most of them have rather basic computer skills.
So these users sometimes bring a USB memory from home, infected with some virus which the company antivirus does disinfect, but the effects (hidden folders or files moved to a directory with a blank name, among others) are not always reversed.
So you see, I would prefer distributing an executable which fixes the memory for them rather than having them come into my office and make me reboot to Windows just to remove the hidden attribute from their folders or so on.
Besides, if in my application I specifically set console codepage to UTF8 for the Windows version of the executable, and I am calling a D function (supposedly portable) to rename or delete a directory, and yet it does not get deleted, supposedly because it is being used (which I have tried to avoid in my code), I find this rather odd, and since I am new to D, I do not yet know the internals of the language well enough to realize where the problem is.
Which is why I am asking for help here :)
|
January 17, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hugo Florentino | Does it fail for that one directory only or for any directory? |
January 17, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Fri, 17 Jan 2014 07:07:35 +0000, Kagamin wrote:
> Does it fail for that one directory only or for any directory?
Interesting question. I would have to do more tests with odd names, but apparently both remove() and rename() have problems with directories with a blank name.
Curiously, moving files or directories from within that blank directory to another directory seems to working correctly, so it's not like the directory is not being detected.
I haven't dived in the code for both functions, but I suspect that some validation may be causing the problem.
|
January 17, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hugo Florentino | I only noticed that rename uses MOVEFILE_REPLACE_EXISTING flag, which can't be used with directories. Are you sure remove fails too? If rename throws, remove is not called in your code. |
January 18, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Fri, 17 Jan 2014 13:10:00 +0000, Kagamin wrote:
> I only noticed that rename uses MOVEFILE_REPLACE_EXISTING flag, which
> can't be used with directories. Are you sure remove fails too? If
> rename throws, remove is not called in your code.
Well, as a matter of fact I did try to use remove directly and it failed with the same problem (directory in use by some process)
Since subdirectories were being moved just fine, I thought once the content of the problematic directory was moved elsewhere I could rename the directory first and then remove it, but this approach failed too, at least from Windows.
|
January 18, 2014 Re: errors with filesystem operations | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hugo Florentino | On Friday, 17 January 2014 at 12:52:09 UTC, Hugo Florentino wrote:
> On Fri, 17 Jan 2014 07:07:35 +0000, Kagamin wrote:
>> Does it fail for that one directory only or for any directory?
>
> Interesting question. I would have to do more tests with odd names, but apparently both remove() and rename() have problems with directories with a blank name.
In that case try a path with \\?\ prefix (unparsed path).
|
Copyright © 1999-2021 by the D Language Foundation