diff options
author | Jan Dubois <jand@activestate.com> | 2006-12-19 05:49:40 -0800 |
---|---|---|
committer | Steve Peters <steve@fisharerojo.org> | 2006-12-20 04:07:11 +0000 |
commit | 35cf1ab6c6ff4f898ef39b9c22313127bcebffc4 (patch) | |
tree | e8caa4c8db555dedf744efb4f9fb6f03117b5077 /win32 | |
parent | 1a9d5acd934f27528a46676584a082ccd7e01693 (diff) | |
download | perl-35cf1ab6c6ff4f898ef39b9c22313127bcebffc4.tar.gz |
let readdir() return the alternate (short) filename if the long name is outside the current codepage
Message-ID: <8nmgo2dr5gtmv00gtfu07g7rdgitr859jk@4ax.com>
p4raw-id: //depot/perl@29597
Diffstat (limited to 'win32')
-rw-r--r-- | win32/win32.c | 69 |
1 files changed, 60 insertions, 9 deletions
diff --git a/win32/win32.c b/win32/win32.c index c312c554f6..3d00bb895e 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -18,6 +18,9 @@ #ifndef HWND_MESSAGE # define HWND_MESSAGE ((HWND)-3) #endif +#ifndef WC_NO_BEST_FIT_CHARS +# define WC_NO_BEST_FIT_CHARS 0x00000400 +#endif #include <winnt.h> #include <io.h> #include <signal.h> @@ -752,6 +755,10 @@ win32_opendir(const char *filename) char scanname[MAX_PATH+3]; Stat_t sbuf; WIN32_FIND_DATAA aFindData; + WIN32_FIND_DATAW wFindData; + bool using_wide; + char buffer[MAX_PATH*2]; + char *ptr; len = strlen(filename); if (len > MAX_PATH) @@ -779,7 +786,15 @@ win32_opendir(const char *filename) scanname[len] = '\0'; /* do the FindFirstFile call */ - dirp->handle = FindFirstFileA(PerlDir_mapA(scanname), &aFindData); + if (IsWinNT()) { + WCHAR wscanname[sizeof(scanname)]; + MultiByteToWideChar(CP_ACP, 0, scanname, -1, wscanname, sizeof(wscanname)/sizeof(WCHAR)); + dirp->handle = FindFirstFileW(PerlDir_mapW(wscanname), &wFindData); + using_wide = TRUE; + } + else { + dirp->handle = FindFirstFileA(PerlDir_mapA(scanname), &aFindData); + } if (dirp->handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); /* FindFirstFile() fails on empty drives! */ @@ -801,16 +816,31 @@ win32_opendir(const char *filename) return NULL; } + if (using_wide) { + BOOL use_default = FALSE; + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, + wFindData.cFileName, -1, + buffer, sizeof(buffer), NULL, &use_default); + if (use_default && *wFindData.cAlternateFileName) { + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, + wFindData.cAlternateFileName, -1, + buffer, sizeof(buffer), NULL, NULL); + } + ptr = buffer; + } + else { + ptr = aFindData.cFileName; + } /* now allocate the first part of the string table for * the filenames that we find. */ - idx = strlen(aFindData.cFileName)+1; + idx = strlen(ptr)+1; if (idx < 256) - dirp->size = 128; + dirp->size = 256; else dirp->size = idx; Newx(dirp->start, dirp->size, char); - strcpy(dirp->start, aFindData.cFileName); + strcpy(dirp->start, ptr); dirp->nfiles++; dirp->end = dirp->curr = dirp->start; dirp->end += idx; @@ -839,16 +869,37 @@ win32_readdir(DIR *dirp) dirp->curr += len + 1; if (dirp->curr >= dirp->end) { dTHX; - BOOL res; - WIN32_FIND_DATAA aFindData; + BOOL res; + WIN32_FIND_DATAA aFindData; + char buffer[MAX_PATH*2]; + char *ptr; /* finding the next file that matches the wildcard * (which should be all of them in this directory!). */ - res = FindNextFileA(dirp->handle, &aFindData); + if (IsWinNT()) { + WIN32_FIND_DATAW wFindData; + res = FindNextFileW(dirp->handle, &wFindData); + if (res) { + BOOL use_default = FALSE; + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, + wFindData.cFileName, -1, + buffer, sizeof(buffer), NULL, &use_default); + if (use_default && *wFindData.cAlternateFileName) { + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, + wFindData.cAlternateFileName, -1, + buffer, sizeof(buffer), NULL, NULL); + } + ptr = buffer; + } + } + else { + res = FindNextFileA(dirp->handle, &aFindData); + ptr = aFindData.cFileName; + } if (res) { long endpos = dirp->end - dirp->start; - long newsize = endpos + strlen(aFindData.cFileName) + 1; + long newsize = endpos + strlen(ptr) + 1; /* bump the string table size by enough for the * new name and its null terminator */ while (newsize > dirp->size) { @@ -857,7 +908,7 @@ win32_readdir(DIR *dirp) Renew(dirp->start, dirp->size, char); dirp->curr = dirp->start + curpos; } - strcpy(dirp->start + endpos, aFindData.cFileName); + strcpy(dirp->start + endpos, ptr); dirp->end = dirp->start + newsize; dirp->nfiles++; } |