@@ -958,17 +958,35 @@ extern "C" LEAN_EXPORT obj_res lean_io_realpath(obj_arg fname, obj_arg) {
958958#if defined(LEAN_WINDOWS)
959959 constexpr unsigned BufferSize = 8192 ;
960960 char buffer[BufferSize];
961- DWORD retval = GetFullPathName (string_cstr (fname), BufferSize, buffer, nullptr );
961+ HANDLE handle = CreateFile (string_cstr (fname), 0 , FILE_SHARE_READ, NULL , OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
962+ if (handle == INVALID_HANDLE_VALUE) {
963+ obj_res res = mk_file_not_found_error (fname);
964+ dec_ref (fname);
965+ return res;
966+ }
967+ DWORD retval = GetFinalPathNameByHandle (handle, buffer, BufferSize, 0 );
968+ CloseHandle (handle);
962969 if (retval == 0 || retval > BufferSize) {
963970 return io_result_mk_ok (fname);
964971 } else {
965972 dec_ref (fname);
973+ char * res = buffer;
974+ if (memcmp (res, " \\\\ ?\\ " , 4 ) == 0 ) {
975+ if (memcmp (res + 4 , " UNC\\ " , 4 ) == 0 ) {
976+ // network path: convert "\\\\?\\UNC\\..." to "\\\\..."
977+ res[6 ] = ' \\ ' ;
978+ res += 6 ;
979+ } else {
980+ // simple path: convert "\\\\?\\C:\\.." to "C:\\..."
981+ res += 4 ;
982+ }
983+ }
966984 // Hack for making sure disk is lower case
967985 // TODO(Leo): more robust solution
968- if (strlen (buffer ) >= 2 && buffer [1 ] == ' :' ) {
969- buffer [0 ] = tolower (buffer [0 ]);
986+ if (strlen (res ) >= 2 && res [1 ] == ' :' ) {
987+ res [0 ] = tolower (res [0 ]);
970988 }
971- return io_result_mk_ok (mk_string (buffer ));
989+ return io_result_mk_ok (mk_string (res ));
972990 }
973991#else
974992 char buffer[PATH_MAX];
0 commit comments