Euphoria
Ticket #696:
file operations on network share not working
-
Reported by
euphoric
Jul 25, 2011
On Microsoft Windows 7, this is some debug output from my program:
using copy_file( "\\SEMP1\iNet_Server\htdocs\files\data\ALPHA (TEST2).txt","\
\SEMP1\iNet_Server\htdocs\files\data\backup\ALPHA (TEST2).txt",1)
Failed to copy with copy_file(), using system()
1 file(s) copied.
using copy_file( "\\SEMP1\iNet_Server\htdocs\files\data\ALPHA (TEST).txt","\\
SEMP1\iNet_Server\htdocs\files\data\backup\ALPHA (TEST).txt",1)
Failed to copy with copy_file(), using system()
1 file(s) copied.
File 1: "\\SEMP1\iNet_Server\htdocs\files\data\ALPHA (TEST2).txt"
COULD NOT READ!
File 2: "\\SEMP1\iNet_Server\htdocs\files\data\ALPHA (TEST).txt"
COULD NOT READ!
As you can see, copy_file() is failing, but the system() copy works. Also, it is read_lines() that is failing to read the files.
This works for local files.
Details
1. Comment by mattlewis
Jul 25, 2011
Can you open anything on the network share (e.g., using read_lines)? What about if you map the share to a network drive?
2. Comment by DerekParnell
Jul 26, 2011
I suspect a 'permissions' problem, maybe isolated to Windows 7.
Using either copy_file() or read_lines() for shares on my WinXP system works just fine.
3. Comment by euphoric
Jul 26, 2011
The following program produces the output below:
include std/filesys.e
include std/console.e
include std/io.e
sequence
NETWDIR = "\\SEMP1\\htdocs\\files\\",
FILEDIR = "U:\\htdocs\\files\\",
FILEEXT = "*.esp"
object files = dir( NETWDIR & FILEEXT )
if sequence(files) then
printf(1,"\n%d",{length(files)})
else
puts(1,"\nFAIL")
end if
files = dir( FILEDIR & FILEEXT )
if sequence(files) then
printf(1,"\n%d",{length(files)})
puts(1,"\nfilename: '" & files[1][D_NAME] & "'")
object filetxt = read_lines( FILEDIR & files[1][D_NAME] )
if integer(filetxt) then
puts(1,"\nread_lines() FAIL" )
else
puts(1,"\nread_lines() SUCCESS" )
end if
else
puts(1,"\nFAIL")
end if
puts(1,"\n\n")
maybe_any_key()
Output from above is:
FAIL
18
filename: 'addinventory.esp'
read_lines() SUCCESS
Press Any Key to continue...
Apparently, nothing will open on the network share, and I can't even get a dir() listing. I don't think this is a permissions issue, unless I just don't fully understand what's going on.
4. Comment by mattlewis
Jul 26, 2011
After the call to CopyFileA fails, what does GetLastError return? Or after the call to dir, even (which uses FindFirstFile).
5. Comment by DerekParnell
Jul 26, 2011
Is the path syntax correct for the share reference? Shouldn't it begin with two slashes such as ...
NETWDIR = "\\\\SEMP1\\htdocs\\files\\"
or in Eu4 usage ...
NETWDIR = `\\SEMP1\htdocs\files\`
6. Comment by euphoric
Jul 26, 2011
Derek, you are right. Good eye! :)
But it doesn't matter. The original program with which I discovered the error reads the file paths from a text file and doesn't have this "typo." The typo only exists in the example, and, once fixed, makes no difference.
matt, I have no idea. Is there a way to modify my example program (above) to give that information?
7. Comment by mattlewis
Jul 26, 2011
Here's how you wrap GetLastError:
include std/dll.e
constant
K32 = open_dll("kernel32.dll"),
GETLASTERROR = define_c_func( K32, "GetLastError", {}, C_INT )
-- and then to use it:
? c_func( GETLASTERROR, {} )
8. Comment by euphoric
Jul 26, 2011
Revised output with GetLastError() call:
Using network path "\\SEMP1\htdocs\files\"
FAIL
GetLastError(): 87
Using network path "U:\htdocs\files\"
file count: 18
filename: 'addinventory.esp'
read_lines() SUCCESS
Press Any Key to continue...
The updated code:
include std/filesys.e
include std/console.e
include std/io.e
include std/dll.e
constant
K32 = open_dll("kernel32.dll"),
GETLASTERROR = define_c_func( K32, "GetLastError", {}, C_INT )
sequence
NETWDIR = "\\\\SEMP1\\htdocs\\files\\",
FILEDIR = "U:\\htdocs\\files\\",
FILEEXT = "*.esp"
object files = dir( NETWDIR & FILEEXT )
puts(1,"\nUsing network path \"" & NETWDIR & "\"")
if sequence(files) then
printf(1,"\n\tfile count: %d",{length(files)})
else
printf(1,"\n\tFAIL\n\tGetLastError(): %d",{c_func( GETLASTERROR, {} )})
end if
files = dir( FILEDIR & FILEEXT )
puts(1,"\n\nUsing network path \"" & FILEDIR & "\"")
if sequence(files) then
printf(1,"\n\tfile count: %d",{length(files)})
puts(1,"\n\tfilename: '" & files[1][D_NAME] & "'")
object filetxt = read_lines( FILEDIR & files[1][D_NAME] )
if integer(filetxt) then
puts(1,"\n\tread_lines() FAIL" )
else
puts(1,"\n\tread_lines() SUCCESS" )
end if
else
printf(1,"\n\tFAIL\n\tGetLastError(): %d",{c_func( GETLASTERROR, {} )})
end if
puts(1,"\n\n")
maybe_any_key()
9. Comment by mattlewis
Jul 26, 2011
In error.h, I find:
#define ERROR_INVALID_PARAMETER 87
My only thought is that somehow we're corrupting the directory as passed. In be_machine.c, find this line:
next_file = FindFirstFile( path, &file_info);
...and add something like this right before it:
printf("FindFirstFile( '%s' )\n", path );
Then see what you get.
10. Comment by euphoric
Jul 26, 2011
Good news: We don't seem to be mangling the path.
Using network path "\\SEMP1\htdocs\files\"
FindFirstFile( '\\SEMP1\htdocs\files\*.esp' )
FindFirstFile( '\\SEMP1\htdocs\files\*.esp\*' )
FAIL
GetLastError(): 67
Using network path "U:\htdocs\files\"
FindFirstFile( 'U:\htdocs\files\*.esp' )
file count: 18
filename: 'addinventory.esp'
read_lines() SUCCESS
Here are results from the commandline of the following commands:
> dir \\SEMP1\htdocs\files\*.esp
The network name cannot be found.
> dir U:\htdocs\files\*.esp
[lists output of specified files]
Don't know why Windows Explorer can get the directory of \\SEMP1\htdocs\files\*.esp OK but not the console interface. Maybe that's a clue and maybe it' isn't. I really don't know.
11. Comment by euphoric
Jul 26, 2011
Hmmmm. Did I mistype '87' the first time? I don't think so, but maybe. Now the error is 67, and consistently 67, which is telling me what the console tells me (ERROR_BAD_NET_NAME).
12. Comment by euphoric
Jul 26, 2011
Oh, no, I didn't mistype it. That was copied verbatim from the console output window...
13. Comment by mattlewis
Jul 26, 2011
Dunno. What about when you try copying stuff? Same error number?
14. Comment by DerekParnell
Jul 26, 2011
I still think this is an operating system problem and not a Euphoria problem.
I remember that I had a lot of problems getting our home computers to read and write to each others shares (a mixture of Windows 7 and Windows XP machines) and it was only fixed when I ensured that all machines had identical workgroup names.
My research on the issue discovered that changes to networking behaviour in Vista and Win7 was the culprit, and I'm not sure if I've fixed the problem or just got a temporary workaround happening.
15. Comment by euphoric
Jul 27, 2011
I can copy files using the Windows 7 GUI, using the mapped drive or the network URL.
I can copy files programmatically and in the console using a mapped drive.
I cannot copy files programmatically or in the console when using the network URL.
The fact that I cannot do this in the console might be the clue as to why I can't do it programmatically. However, if I can do it via the Windows 7 GUI, then I should be able to do it programmatically.
The PC I'm using is Windows 7. The PC with the files is Windows XP Home. Derek, what's your setup that lets you access files programmatically from a network URL?
I agree it could be an OS issue at this point, but that just doesn't seem right. If I can do it via the GUI, I should be able to do it programmatically. My searches on the 'net don't reveal any particular quirk in this regard. Maybe somebody else can find something.
16. Comment by mattlewis
Jul 27, 2011
UNC paths are not supported by CMD.exe, however, the programmatic version should be able to do this.
Are you certain that you have the path correct? The format is: \\server\share-name\etc . In your case, SEMP1 is the server name and iNet_Server is the name as it is shared by windows.
17. Comment by euphoric
Jul 27, 2011
Matt, that was a problem with the test code. When I changed the line (below) in the test code above, it works.
NETWDIR = "\\\\SEMP1\\iNet_Server\\htdocs\\files\\",
I get this output:
Using network path "\\SEMP1\iNet_Server\htdocs\files\"
file count: 18
Using network path "U:\htdocs\files\"
file count: 18
filename: 'addinventory.esp'
read_lines() SUCCESS
Press Any Key to continue...
I am exploring this morning why my original program isn't working properly. Will report back.
Update: Looks like I was adding unneeded quotes around file paths with spaces in them. This was probably a holdover from when I was using the system() command for this. I'm updating code to be 4.0-compatible and use 4.0 features, so apparently I just missed this.
FFFFFFFUUUUUU!!!!!!!