Re: Error: file name for OPEN is too long
- Posted by Matt Lewis <matthewwalkerlewis at g?ail.?om> Dec 21, 2007
- 552 views
Here is some code that will allow you to open files with larger path names using the wide version of CreateFile. I think it requires the full absolute path, including the Drive letter (at least, that's the only way I've gotten it to work. Of course, you'll also have to wrap the ReadFile and WriteFile routines from win32, as well, though it's not too hard.
include machine.e include dll.e constant kernel32 = open_dll("kernel32.dll"), CreateFileW = define_c_func( kernel32, "CreateFileW", repeat(C_POINTER, 7), C_INT ), MultiByteToWideChar = define_c_func( kernel32, "MultiByteToWideChar", { C_UINT, C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG}, C_LONG), OF_READ = 0, OF_READWRITE = 2, OF_WRITE= 1 global function allocate_unicode( sequence ansi ) atom uni_ptr, ansi_ptr, ok integer ansi_len, uni_len ansi_len = length( ansi ) + 1 uni_len = ansi_len * 2 + 2 ansi_ptr = allocate_string( ansi ) uni_ptr = allocate( uni_len ) -- now convert the string ok = c_func( MultiByteToWideChar, { 0, -- code page 0, -- flags ansi_ptr, -- ptr to string ansi_len, -- length of string uni_ptr, -- ptr to buffer for return value uni_len -- length of buffer } ) ? ok free( ansi_ptr ) return uni_ptr end function constant MODE = "ruw", OF_MODE = {OF_READ, OF_READWRITE, OF_WRITE }, CREATE_ALWAYS = 2, CREATE_NEW = 1, OPEN_ALWAYS = 4, OPEN_EXISTING = 3, TRUNCATE_EXISTING = 5 global function open_long( sequence path, sequence mode ) atom uni_ptr atom handle integer OF, creationDisposition path = "\\\\?\\" & path uni_ptr = allocate_unicode( path ) OF = OF_MODE[ find( mode[1], MODE )] if OF = OF_READ then creationDisposition = OPEN_EXISTING elsif OF = OF_READWRITE then creationDisposition = OPEN_EXISTING elsif OF = OF_WRITE then creationDisposition = CREATE_ALWAYS end if handle = c_func( CreateFileW, { uni_ptr, OF, 0, 0, creationDisposition, 0, 0 }) free(uni_ptr) return handle end function