X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2985ad5deecdcb48611ea71ac43e3c2f256c4c08..d9f7f49ea3aca3e0e0beafe648a61e6606e37663:/src/common/filefn.cpp diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp index 1cfa5825c5..b9c3a8e7ee 100644 --- a/src/common/filefn.cpp +++ b/src/common/filefn.cpp @@ -115,11 +115,11 @@ extern wxChar *wxBuffer; -#if defined(__WXMAC__) && !defined(__UNIX__) - #include "morefile.h" - #include "moreextr.h" - #include "fullpath.h" - #include "fspcompa.h" +#ifdef __WXMAC__ +# include "MoreFiles.h" +# include "MoreFilesExtras.h" +# include "FullPath.h" +# include "FSpCompat.h" #endif IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxStringList) @@ -143,7 +143,7 @@ const off_t wxInvalidOffset = (off_t)-1; // ---------------------------------------------------------------------------- // we need to translate Mac filenames before passing them to OS functions - #define OS_FILENAME(s) (s.fn_str()) +#define OS_FILENAME(s) (s.fn_str()) // ============================================================================ // implementation @@ -272,8 +272,11 @@ wxString wxPathList::FindAbsoluteValidPath (const wxString& file) bool wxFileExists (const wxString& filename) { -#ifdef __GNUWIN32__ // (fix a B20 bug) - return GetFileAttributes(filename) != 0xFFFFFFFF; +#ifdef __WINDOWS__ + // GetFileAttributes can copy with network paths + DWORD ret = GetFileAttributes(filename); + DWORD isDir = (ret & FILE_ATTRIBUTE_DIRECTORY); + return ((ret != 0xffffffff) && (isDir == 0)); #else wxStructStat stbuf; if ( !filename.empty() && wxStat (OS_FILENAME(filename), &stbuf) == 0 ) @@ -286,33 +289,33 @@ wxFileExists (const wxString& filename) bool wxIsAbsolutePath (const wxString& filename) { -#ifdef __WXMAC__ if (filename != wxT("")) { +#if defined(__WXMAC__) && !defined(__DARWIN__) + // Classic or Carbon CodeWarrior like + // Carbon with Apple DevTools is Unix like + // This seems wrong to me, but there is no fix. since // "MacOS:MyText.txt" is absolute whereas "MyDir:MyText.txt" // is not. Or maybe ":MyDir:MyText.txt" has to be used? RR. - if (filename.Find(':') != wxNOT_FOUND && filename[0] != ':') return TRUE ; - } - return FALSE ; #else - if (filename != wxT("")) - { - if (filename[0] == wxT('/') + // Unix like or Windows + if (filename[0] == wxT('/')) + return TRUE; +#endif #ifdef __VMS__ - || (filename[0] == wxT('[') && filename[1] != wxT('.')) + if ((filename[0] == wxT('[') && filename[1] != wxT('.'))) + return TRUE; #endif #ifdef __WINDOWS__ - /* MSDOS */ - || filename[0] == wxT('\\') || (wxIsalpha (filename[0]) && filename[1] == wxT(':')) + // MSDOS like + if (filename[0] == wxT('\\') || (wxIsalpha (filename[0]) && filename[1] == wxT(':'))) + return TRUE; #endif - ) - return TRUE; } - return FALSE; -#endif + return FALSE ; } /* @@ -655,265 +658,308 @@ wxContractPath (const wxString& filename, const wxString& envname, const wxStrin // (basename) wxChar *wxFileNameFromPath (wxChar *path) { - if (path) + if (path) { - register wxChar *tcp; - - tcp = path + wxStrlen (path); - while (--tcp >= path) + register wxChar *tcp; + + tcp = path + wxStrlen (path); + while (--tcp >= path) { -#ifdef __WXMAC__ - if (*tcp == wxT(':') ) +#if defined(__WXMAC__) && !defined(__DARWIN__) + // Classic or Carbon CodeWarrior like + // Carbon with Apple DevTools is Unix like + if (*tcp == wxT(':')) + return tcp + 1; #else - if (*tcp == wxT('/') || *tcp == wxT('\\') -#ifdef __VMS__ - || *tcp == wxT(':') || *tcp == wxT(']')) -#else - ) + // Unix like or Windows + if (*tcp == wxT('/') || *tcp == wxT('\\')) + return tcp + 1; #endif +#ifdef __VMS__ + if (*tcp == wxT(':') || *tcp == wxT(']')) + return tcp + 1; #endif - return tcp + 1; - } /* while */ + } /* while */ #if defined(__WXMSW__) || defined(__WXPM__) - if (wxIsalpha (*path) && *(path + 1) == wxT(':')) - return path + 2; + // MSDOS like + if (wxIsalpha (*path) && *(path + 1) == wxT(':')) + return path + 2; #endif } - return path; + return path; } wxString wxFileNameFromPath (const wxString& path1) { - if (path1 != wxT("")) - { - - wxChar *path = WXSTRINGCAST path1 ; - register wxChar *tcp; - - tcp = path + wxStrlen (path); - while (--tcp >= path) - { -#ifdef __WXMAC__ - if (*tcp == wxT(':') ) -#else - if (*tcp == wxT('/') || *tcp == wxT('\\') -#ifdef __VMS__ - || *tcp == wxT(':') || *tcp == wxT(']')) + if (path1 != wxT("")) + { + wxChar *path = WXSTRINGCAST path1 ; + register wxChar *tcp; + + tcp = path + wxStrlen (path); + while (--tcp >= path) + { +#if defined(__WXMAC__) && !defined(__DARWIN__) + // Classic or Carbon CodeWarrior like + // Carbon with Apple DevTools is Unix like + if (*tcp == wxT(':') ) + return wxString(tcp + 1); #else - ) -#endif + // Unix like or Windows + if (*tcp == wxT('/') || *tcp == wxT('\\')) + return wxString(tcp + 1); #endif +#ifdef __VMS__ + if (*tcp == wxT(':') || *tcp == wxT(']')) return wxString(tcp + 1); - } /* while */ +#endif + } /* while */ #if defined(__WXMSW__) || defined(__WXPM__) - if (wxIsalpha (*path) && *(path + 1) == wxT(':')) + // MSDOS like + if (wxIsalpha (*path) && *(path + 1) == wxT(':')) return wxString(path + 2); #endif } - // Yes, this should return the path, not an empty string, otherwise - // we get "thing.txt" -> "". - return path1; + // Yes, this should return the path, not an empty string, otherwise + // we get "thing.txt" -> "". + return path1; } // Return just the directory, or NULL if no directory wxChar * wxPathOnly (wxChar *path) { - if (path && *path) + if (path && *path) { - static wxChar buf[_MAXPATHLEN]; - - // Local copy - wxStrcpy (buf, path); - - int l = wxStrlen(path); - bool done = FALSE; - - int i = l - 1; - - // Search backward for a backward or forward slash - while (!done && i > -1) - { - // ] is for VMS -#ifdef __WXMAC__ - if (path[i] == wxT(':') ) + static wxChar buf[_MAXPATHLEN]; + + // Local copy + wxStrcpy (buf, path); + + int l = wxStrlen(path); + int i = l - 1; + + // Search backward for a backward or forward slash + while (i > -1) + { +#if defined(__WXMAC__) && !defined(__DARWIN__) + // Classic or Carbon CodeWarrior like + // Carbon with Apple DevTools is Unix like + if (path[i] == wxT(':') ) + { + buf[i] = 0; + return buf; + } #else - if (path[i] == wxT('/') || path[i] == wxT('\\') || path[i] == wxT(']')) + // Unix like or Windows + if (path[i] == wxT('/') || path[i] == wxT('\\')) + { + buf[i] = 0; + return buf; + } #endif - { - done = TRUE; #ifdef __VMS__ - if ( path[i] == wxT(']') ) - buf[i+1] = 0; - else + if (path[i] == wxT(']')) + { + buf[i+1] = 0; + return buf; + } #endif - buf[i] = 0; - - return buf; + i --; } - else i --; - } - + #if defined(__WXMSW__) || defined(__WXPM__) - // Try Drive specifier - if (wxIsalpha (buf[0]) && buf[1] == wxT(':')) + // Try Drive specifier + if (wxIsalpha (buf[0]) && buf[1] == wxT(':')) { - // A:junk --> A:. (since A:.\junk Not A:\junk) - buf[2] = wxT('.'); - buf[3] = wxT('\0'); - return buf; + // A:junk --> A:. (since A:.\junk Not A:\junk) + buf[2] = wxT('.'); + buf[3] = wxT('\0'); + return buf; } #endif } - - return (wxChar *) NULL; + return (wxChar *) NULL; } // Return just the directory, or NULL if no directory wxString wxPathOnly (const wxString& path) { - if (path != wxT("")) + if (path != wxT("")) { - wxChar buf[_MAXPATHLEN]; - - // Local copy - wxStrcpy (buf, WXSTRINGCAST path); - - int l = path.Length(); - bool done = FALSE; - - int i = l - 1; - - // Search backward for a backward or forward slash - while (!done && i > -1) - { - // ] is for VMS -#ifdef __WXMAC__ - if (path[i] == wxT(':') ) + wxChar buf[_MAXPATHLEN]; + + // Local copy + wxStrcpy (buf, WXSTRINGCAST path); + + int l = path.Length(); + int i = l - 1; + + // Search backward for a backward or forward slash + while (i > -1) + { +#if defined(__WXMAC__) && !defined(__DARWIN__) + // Classic or Carbon CodeWarrior like + // Carbon with Apple DevTools is Unix like + if (path[i] == wxT(':') ) + { + buf[i] = 0; + return wxString(buf); + } #else - if (path[i] == wxT('/') || path[i] == wxT('\\') || path[i] == wxT(']')) + // Unix like or Windows + if (path[i] == wxT('/') || path[i] == wxT('\\')) + { + buf[i] = 0; + return wxString(buf); + } #endif - { - done = TRUE; #ifdef __VMS__ - if ( path[i] == wxT(']') ) - buf[i+1] = 0; - else + if (path[i] == wxT(']')) + { + buf[i+1] = 0; + return wxString(buf); + } #endif - buf[i] = 0; - - return wxString(buf); + i --; } - else i --; - } - + #if defined(__WXMSW__) || defined(__WXPM__) - // Try Drive specifier - if (wxIsalpha (buf[0]) && buf[1] == wxT(':')) + // Try Drive specifier + if (wxIsalpha (buf[0]) && buf[1] == wxT(':')) { - // A:junk --> A:. (since A:.\junk Not A:\junk) - buf[2] = wxT('.'); - buf[3] = wxT('\0'); - return wxString(buf); + // A:junk --> A:. (since A:.\junk Not A:\junk) + buf[2] = wxT('.'); + buf[3] = wxT('\0'); + return wxString(buf); } #endif } - - return wxString(wxT("")); + return wxString(wxT("")); } // Utility for converting delimiters in DOS filenames to UNIX style // and back again - or we get nasty problems with delimiters. // Also, convert to lower case, since case is significant in UNIX. -#if defined(__WXMAC__) && !defined(__UNIX__) +#if defined(__WXMAC__) wxString wxMacFSSpec2MacFilename( const FSSpec *spec ) { +#ifdef __DARWIN__ + FSRef theRef; + char thePath[FILENAME_MAX]; + + // convert the FSSpec to an FSRef + (void) FSpMakeFSRef( spec, &theRef ); + // get the POSIX path associated with the FSRef + (void) FSRefMakePath( &theRef, (UInt8 *)thePath, sizeof(thePath) ); + + // create path string for return value + wxString result( thePath ) ; +#else Handle myPath ; short length ; + // get length of path and allocate handle FSpGetFullPath( spec , &length , &myPath ) ; ::SetHandleSize( myPath , length + 1 ) ; ::HLock( myPath ) ; (*myPath)[length] = 0 ; - if ( length > 0 && (*myPath)[length-1] ==':' ) + if ((length > 0) && ((*myPath)[length-1] == ':')) (*myPath)[length-1] = 0 ; + + // create path string for return value + wxString result( (char*) *myPath ) ; - wxString result( (char*) *myPath ) ; + // free allocated handle ::HUnlock( myPath ) ; ::DisposeHandle( myPath ) ; +#endif + return result ; } void wxMacFilename2FSSpec( const char *path , FSSpec *spec ) { - FSpLocationFromFullPath( strlen(path ) , path , spec ) ; +#ifdef __DARWIN__ + FSRef theRef; + + // get the FSRef associated with the POSIX path + (void) FSPathMakeRef((const UInt8 *) path, &theRef, NULL); + // convert the FSRef to an FSSpec + (void) FSGetCatalogInfo(&theRef, kFSCatInfoNone, NULL, NULL, spec, NULL); +#else + FSpLocationFromFullPath( strlen(path) , path , spec ) ; +#endif } +#ifndef __DARWIN__ +// Mac file names are POSIX (Unix style) under Darwin +// therefore the conversion functions below are not needed + static char sMacFileNameConversion[ 1000 ] ; wxString wxMac2UnixFilename (const char *str) { char *s = sMacFileNameConversion ; strcpy( s , str ) ; - if (s) - { - memmove( s+1 , s ,strlen( s ) + 1) ; - if ( *s == ':' ) + if (s) + { + memmove( s+1 , s ,strlen( s ) + 1) ; + if ( *s == ':' ) *s = '.' ; - else + else *s = '/' ; - - while (*s) - { + + while (*s) + { if (*s == ':') - *s = '/'; + *s = '/'; else - *s = wxTolower (*s); // Case INDEPENDENT + *s = wxTolower(*s); // Case INDEPENDENT s++; + } } - } - return wxString (sMacFileNameConversion) ; + return wxString(sMacFileNameConversion) ; } wxString wxUnix2MacFilename (const char *str) { char *s = sMacFileNameConversion ; strcpy( s , str ) ; - if (s) - { - if ( *s == '.' ) - { - // relative path , since it goes on with slash which is translated to a : - memmove( s , s+1 ,strlen( s ) ) ; - } - else if ( *s == '/' ) + if (s) { - // absolute path -> on mac just start with the drive name - memmove( s , s+1 ,strlen( s ) ) ; - } - else - { - wxASSERT_MSG( 1 , "unkown path beginning" ) ; - } - while (*s) - { - if (*s == '/' || *s == '\\') - { - // convert any back-directory situations - if ( *(s+1) == '.' && *(s+2) == '.' && ( (*(s+3) == '/' || *(s+3) == '\\') ) ) - { - *s = ':'; - memmove( s+1 , s+3 ,strlen( s+3 ) + 1 ) ; - } - else - *s = ':'; - } - - s++ ; + if ( *s == '.' ) + { + // relative path , since it goes on with slash which is translated to a : + memmove( s , s+1 ,strlen( s ) ) ; + } + else if ( *s == '/' ) + { + // absolute path -> on mac just start with the drive name + memmove( s , s+1 ,strlen( s ) ) ; + } + else + { + wxASSERT_MSG( 1 , "unkown path beginning" ) ; + } + while (*s) + { + if (*s == '/' || *s == '\\') + { + // convert any back-directory situations + if ( *(s+1) == '.' && *(s+2) == '.' && ( (*(s+3) == '/' || *(s+3) == '\\') ) ) + { + *s = ':'; + memmove( s+1 , s+3 ,strlen( s+3 ) + 1 ) ; + } + else + *s = ':'; + } + s++ ; + } } - } - return wxString (sMacFileNameConversion) ; + return wxString (sMacFileNameConversion) ; } wxString wxMacFSSpec2UnixFilename( const FSSpec *spec ) @@ -926,8 +972,10 @@ void wxUnixFilename2FSSpec( const char *path , FSSpec *spec ) wxString var = wxUnix2MacFilename( path ) ; wxMacFilename2FSSpec( var , spec ) ; } +#endif // ! __DARWIN__ + +#endif // __WXMAC__ -#endif void wxDos2UnixFilename (char *s) { @@ -1012,6 +1060,11 @@ wxCopyFile (const wxString& file1, const wxString& file2, bool overwrite) // // NB: 3rd parameter is bFailIfExists i.e. the inverse of overwrite return ::CopyFile(file1, file2, !overwrite) != 0; +#elif defined(__WXPM__) + if (::DosCopy(file2, file2, overwrite ? DCPY_EXISTING : 0) == 0) + return TRUE; + else + return FALSE; #else // !Win32 wxStructStat fbuf; @@ -1138,7 +1191,7 @@ bool wxMkdir(const wxString& dir, int perm) #elif defined(__WXPM__) if (::DosCreateDir((PSZ)dirname, NULL) != 0) // enhance for EAB's?? #else // !MSW and !OS/2 VAC++ - (void)perm; + (void)perm; if ( wxMkDir(wxFNSTRINGCAST wxFNCONV(dirname)) != 0 ) #endif // !MSW/MSW { @@ -1179,13 +1232,20 @@ bool wxPathExists(const wxChar *pszPathName) while ( wxEndsWithPathSeparator(strPath) ) { size_t len = strPath.length(); - if ( len == 1 || strPath[len - 1] == _T(':') ) + if ( len == 1 || (len == 3 && strPath[len - 2] == _T(':')) ) break; strPath.Truncate(len - 1); } #endif // __WINDOWS__ +#ifdef __WINDOWS__ + // Stat can't cope with network paths + DWORD ret = GetFileAttributes(strPath.c_str()); + DWORD isDir = (ret & FILE_ATTRIBUTE_DIRECTORY); + return ((ret != 0xffffffff) && (isDir != 0)); +#else + wxStructStat st; #ifndef __VISAGECPP__ return wxStat(wxFNSTRINGCAST strPath.fn_str(), &st) == 0 && @@ -1196,6 +1256,7 @@ bool wxPathExists(const wxChar *pszPathName) (st.st_mode == S_IFDIR); #endif +#endif } // Get a temporary filename, opening and closing the file. @@ -1258,7 +1319,7 @@ bool wxGetTempFileName(const wxString& prefix, wxString& buf) // Get first file name matching given wild card. -#ifdef __UNIX__ +#if defined(__UNIX__) // Get first file name matching given wild card. // Flags are reserved for future use. @@ -1409,21 +1470,21 @@ struct MacDirectoryIterator static int g_iter_flags ; static MacDirectoryIterator g_iter ; +wxString g_iter_spec ; wxString wxFindFirstFile(const wxChar *spec, int flags) { wxString result; + g_iter_spec = spec ; + g_iter_spec.MakeUpper() ; g_iter_flags = flags; /* MATTHEW: [5] Remember flags */ // Find path only so we can concatenate found file onto path wxString path(wxPathOnly(spec)); - if ( !path.IsEmpty() ) - result << path << wxT('\\'); - FSSpec fsspec ; - wxMacFilename2FSSpec( result , &fsspec ) ; + wxMacFilename2FSSpec( path , &fsspec ) ; g_iter.m_CPB.hFileInfo.ioVRefNum = fsspec.vRefNum ; g_iter.m_CPB.hFileInfo.ioNamePtr = g_iter.m_name ; g_iter.m_index = 0 ; @@ -1441,37 +1502,44 @@ wxString wxFindNextFile() wxString result; short err = noErr ; - - while ( err == noErr ) + wxString name ; + + while(1) { - g_iter.m_index++ ; - g_iter.m_CPB.dirInfo.ioFDirIndex = g_iter.m_index; - g_iter.m_CPB.dirInfo.ioDrDirID = g_iter.m_dirId; /* we need to do this every time */ - err = PBGetCatInfoSync((CInfoPBPtr)&g_iter.m_CPB); - if ( err != noErr ) - break ; + while ( err == noErr ) + { + g_iter.m_index++ ; + g_iter.m_CPB.dirInfo.ioFDirIndex = g_iter.m_index; + g_iter.m_CPB.dirInfo.ioDrDirID = g_iter.m_dirId; /* we need to do this every time */ + err = PBGetCatInfoSync((CInfoPBPtr)&g_iter.m_CPB); + if ( err != noErr ) + break ; - if ( ( g_iter.m_CPB.dirInfo.ioFlAttrib & ioDirMask) != 0 && (g_iter_flags & wxDIR) ) // we have a directory - break ; + if ( ( g_iter.m_CPB.dirInfo.ioFlAttrib & ioDirMask) != 0 && (g_iter_flags & wxDIR) ) // we have a directory + break ; - if ( ( g_iter.m_CPB.dirInfo.ioFlAttrib & ioDirMask) == 0 && !(g_iter_flags & wxFILE ) ) - continue ; + if ( ( g_iter.m_CPB.dirInfo.ioFlAttrib & ioDirMask) == 0 && !(g_iter_flags & wxFILE ) ) + continue ; - // hit ! - break ; - } - if ( err != noErr ) - { - return wxEmptyString ; - } - FSSpec spec ; + // hit ! + break ; + } + if ( err != noErr ) + { + return wxEmptyString ; + } + FSSpec spec ; - FSMakeFSSpecCompat(g_iter.m_CPB.hFileInfo.ioVRefNum, - g_iter.m_dirId, - g_iter.m_name, - &spec) ; + FSMakeFSSpecCompat(g_iter.m_CPB.hFileInfo.ioVRefNum, + g_iter.m_dirId, + g_iter.m_name, + &spec) ; - return wxMacFSSpec2MacFilename( &spec ) ; + wxString name = wxMacFSSpec2MacFilename( &spec ) ; + if ( g_iter_spec.Right(4)==(":*.*") || g_iter_spec.Right(2)==(":*") || name.Upper().Matches(g_iter_spec) ) + return name ; + } + return wxEmptyString ; } #elif defined(__WXMSW__) @@ -1692,7 +1760,7 @@ wxChar *wxGetWorkingDirectory(wxChar *buf, int sz) char *cbuf = new char[sz+1]; #ifdef _MSC_VER if (_getcwd(cbuf, sz) == NULL) { -#elif defined(__WXMAC__) && !defined(__UNIX__) +#elif defined(__WXMAC__) && !defined(__DARWIN__) enum { SFSaveDisk = 0x214, CurDirStore = 0x398 @@ -1710,42 +1778,42 @@ wxChar *wxGetWorkingDirectory(wxChar *buf, int sz) #else // wxUnicode #ifdef _MSC_VER if (_getcwd(buf, sz) == NULL) { -#elif defined(__WXMAC__) && !defined(__UNIX__) - FSSpec cwdSpec ; - FCBPBRec pb; - OSErr error; - Str255 fileName ; - pb.ioNamePtr = (StringPtr) &fileName; - pb.ioVRefNum = 0; - pb.ioRefNum = LMGetCurApRefNum(); - pb.ioFCBIndx = 0; - error = PBGetFCBInfoSync(&pb); - if ( error == noErr ) - { - cwdSpec.vRefNum = pb.ioFCBVRefNum; - cwdSpec.parID = pb.ioFCBParID; - cwdSpec.name[0] = 0 ; - wxString res = wxMacFSSpec2MacFilename( &cwdSpec ) ; - - strcpy( buf , res ) ; - buf[res.length()-1]=0 ; - } - else - buf[0] = 0 ; - /* - this version will not always give back the application directory on mac - enum - { - SFSaveDisk = 0x214, CurDirStore = 0x398 - }; - FSSpec cwdSpec ; - - FSMakeFSSpec( - *(short *) SFSaveDisk , *(long *) CurDirStore , NULL , &cwdSpec ) ; - wxString res = wxMacFSSpec2UnixFilename( &cwdSpec ) ; - strcpy( buf , res ) ; - */ - if (0) { -#elif(__VISAGECPP__) +#elif defined(__WXMAC__) && !defined(__DARWIN__) + FSSpec cwdSpec ; + FCBPBRec pb; + OSErr error; + Str255 fileName ; + pb.ioNamePtr = (StringPtr) &fileName; + pb.ioVRefNum = 0; + pb.ioRefNum = LMGetCurApRefNum(); + pb.ioFCBIndx = 0; + error = PBGetFCBInfoSync(&pb); + if ( error == noErr ) + { + cwdSpec.vRefNum = pb.ioFCBVRefNum; + cwdSpec.parID = pb.ioFCBParID; + cwdSpec.name[0] = 0 ; + wxString res = wxMacFSSpec2MacFilename( &cwdSpec ) ; + + strcpy( buf , res ) ; + buf[res.length()]=0 ; + } + else + buf[0] = 0 ; + /* + this version will not always give back the application directory on mac + enum + { + SFSaveDisk = 0x214, CurDirStore = 0x398 + }; + FSSpec cwdSpec ; + + FSMakeFSSpec( - *(short *) SFSaveDisk , *(long *) CurDirStore , NULL , &cwdSpec ) ; + wxString res = wxMacFSSpec2UnixFilename( &cwdSpec ) ; + strcpy( buf , res ) ; + */ + if (0) { +#elif defined(__VISAGECPP__) || (defined (__OS2__) && defined (__WATCOMC__)) APIRET rc; rc = ::DosQueryCurrentDir( 0 // current drive ,buf