Skip to content

Commit

Permalink
(For Marcel Taeumel) Move the long filename support alloc macros into…
Browse files Browse the repository at this point in the history
… a header

so they can be used in sqWin32FileDirectory.c as well.



git-svn-id: http://squeakvm.org/svn/squeak/trunk@3346 fa1542d4-bde8-0310-ad64-8ed1123d492a
  • Loading branch information
eliotmiranda committed May 17, 2015
1 parent eaa4ba1 commit a2cf869
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 40 deletions.
58 changes: 58 additions & 0 deletions FilePlugin/sqWin32File.h
@@ -0,0 +1,58 @@
#ifndef __SQ_WIN32_FILE_H
#define __SQ_WIN32_FILE_H

/**
Converts multi-byte characters to wide characters. Handles paths longer
than 260 characters (including NULL) by prepending "\\?\" to encode UNC
paths as suggested in http://msdn.microsoft.com/en-us/library/windows/
desktop/aa365247%28v=vs.85%29.aspx#maxpath
"The maximum path of 32,767 characters is approximate,
because the "\\?\" prefix may be expanded to a longer
string by the system at run time, and this expansion
applies to the total length."
Note that we do not check for the correct path component size,
which should be MAX_PATH in general but can vary between file systems.
Actually, we should perform an additional check with
GetVolumneInformation to acquire lpMaximumComponentLength.
Note that another possibility would be to use 8.3 aliases
for path components like the Windows Explorer does. However,
this feature also depends on the volume specifications.
Calling alloca() should be fine because we limit path length to 32k.
Stack size limit is much higher.
When using an API to create a directory, the specified path cannot be
so long that you cannot append an 8.3 file name (that is, the directory
name cannot exceed MAX_PATH minus 12).
**/
#define ALLOC_WIN32_PATH(out_path, in_name, in_size) { \
int sz = MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, NULL, 0); \
if(sz >= 32767) FAIL(); \
if(sz >= MAX_PATH-12 /* for directory creation; see above */) { \
out_path = (WCHAR*)alloca((sz + 4 + 1) * sizeof(WCHAR)); \
out_path[0] = L'\\'; out_path[1] = L'\\'; \
out_path[2] = L'?'; out_path[3] = L'\\'; \
MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path + 4, sz); \
out_path[sz + 4] = 0; \
sz += 4; \
} else { \
out_path = (WCHAR*)alloca((sz + 1) * sizeof(WCHAR)); \
MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path, sz); \
out_path[sz] = 0; \
} \
}

// if(wcscpy_s(in_out_wide_path, in_size < sz ? in_size : sz, tmp) != 0) FAIL(); \
#define REALLOC_WIN32_PATH(in_out_wide_path, in_size) { \
int sz = wcslen(in_out_wide_path); \
WCHAR *tmp = in_out_wide_path; \
in_out_wide_path = (WCHAR*)alloca((in_size+1) * sizeof(WCHAR)); \
if(in_size < sz) tmp[in_size] = 0; \
wcscpy(in_out_wide_path, tmp); \
in_out_wide_path[in_size] = 0; \
}

#endif
42 changes: 2 additions & 40 deletions FilePlugin/sqWin32FilePrims.c
Expand Up @@ -24,6 +24,8 @@
#include "sq.h"
#include "FilePlugin.h"

#include "sqWin32File.h"

extern struct VirtualMachine *interpreterProxy;

#ifdef WIN32_FILE_SUPPORT
Expand Down Expand Up @@ -68,46 +70,6 @@ int thisSession = 0;
/* answers if the file name in question has a case-sensitive duplicate */
int hasCaseSensitiveDuplicate(WCHAR *path);

/**
Converts multi-byte characters to wide characters. Handles paths longer
than 260 characters (including NULL) by prepending "\\?\" to encode UNC
paths as suggested in http://msdn.microsoft.com/en-us/library/windows/
desktop/aa365247%28v=vs.85%29.aspx#maxpath
"The maximum path of 32,767 characters is approximate,
because the "\\?\" prefix may be expanded to a longer
string by the system at run time, and this expansion
applies to the total length."
Note that we do not check for the correct path component size,
which should be MAX_PATH in general but can vary between file systems.
Actually, we should perform an additional check with
GetVolumneInformation to acquire lpMaximumComponentLength.
Note that another possibility would be to use 8.3 aliases
for path components like the Windows Explorer does. However,
this feature also depends on the volume specifications.
Calling alloca() should be fine because we limit path length to 32k.
Stack size limit is much higher.
**/
#define ALLOC_WIN32_PATH(out_path, in_name, in_size) { \
int sz = MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, NULL, 0); \
if(sz >= 32767) FAIL(); \
if(sz >= MAX_PATH) { \
out_path = (WCHAR*)alloca((sz + 4 + 1) * sizeof(WCHAR)); \
out_path[0] = L'\\'; out_path[1] = L'\\'; \
out_path[2] = L'?'; out_path[3] = L'\\'; \
MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path + 4, sz); \
out_path[sz + 4] = 0; \
sz += 4; \
} else { \
out_path = (WCHAR*)alloca((sz + 1) * sizeof(WCHAR)); \
MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path, sz); \
out_path[sz] = 0; \
} \
}


typedef union {
struct {
DWORD dwLow;
Expand Down

0 comments on commit a2cf869

Please sign in to comment.