summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorJan Dubois <jand@activestate.com>2006-12-19 05:49:40 -0800
committerSteve Peters <steve@fisharerojo.org>2006-12-20 04:07:11 +0000
commit35cf1ab6c6ff4f898ef39b9c22313127bcebffc4 (patch)
treee8caa4c8db555dedf744efb4f9fb6f03117b5077 /win32
parent1a9d5acd934f27528a46676584a082ccd7e01693 (diff)
downloadperl-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.c69
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++;
}