|
1 | | -#ifndef __SQ_WIN32_FILE_H |
2 | | -#define __SQ_WIN32_FILE_H |
3 | | - |
4 | | -/** |
5 | | - Converts multi-byte characters to wide characters. Handles paths longer |
6 | | - than 260 characters (including NULL) by prepending "\\?\" to encode UNC |
7 | | - paths as suggested in http://msdn.microsoft.com/en-us/library/windows/ |
8 | | - desktop/aa365247%28v=vs.85%29.aspx#maxpath |
9 | | - "The maximum path of 32,767 characters is approximate, |
10 | | - because the "\\?\" prefix may be expanded to a longer |
11 | | - string by the system at run time, and this expansion |
12 | | - applies to the total length." |
13 | | - |
14 | | - Note that we do not check for the correct path component size, |
15 | | - which should be MAX_PATH in general but can vary between file systems. |
16 | | - Actually, we should perform an additional check with |
17 | | - GetVolumneInformation to acquire lpMaximumComponentLength. |
18 | | -
|
19 | | - Note that another possibility would be to use 8.3 aliases |
20 | | - for path components like the Windows Explorer does. However, |
21 | | - this feature also depends on the volume specifications. |
22 | | -
|
23 | | - Calling alloca() should be fine because we limit path length to 32k. |
24 | | - Stack size limit is much higher. |
25 | | -
|
26 | | - When using an API to create a directory, the specified path cannot be |
27 | | - so long that you cannot append an 8.3 file name (that is, the directory |
28 | | - name cannot exceed MAX_PATH minus 12). |
29 | | -**/ |
30 | | - |
31 | | -#include <malloc.h> |
32 | | - |
33 | | -#define ALLOC_WIN32_PATH(out_path, in_name, in_size) { \ |
34 | | - int sz = MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, NULL, 0); \ |
35 | | - if(sz >= 32767) FAIL(); \ |
36 | | - if(sz >= MAX_PATH-12 /* for directory creation; see above */) { \ |
37 | | - out_path = (WCHAR*)alloca((sz + 4 + 1) * sizeof(WCHAR)); \ |
38 | | - out_path[0] = L'\\'; out_path[1] = L'\\'; \ |
39 | | - out_path[2] = L'?'; out_path[3] = L'\\'; \ |
40 | | - MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path + 4, sz); \ |
41 | | - out_path[sz + 4] = 0; \ |
42 | | - } else { \ |
43 | | - out_path = (WCHAR*)alloca((sz + 1) * sizeof(WCHAR)); \ |
44 | | - MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path, sz); \ |
45 | | - out_path[sz] = 0; \ |
46 | | - } \ |
47 | | -} |
48 | | - |
49 | | -#endif /* __SQ_WIN32_FILE_H */ |
| 1 | +#ifndef __SQ_WIN32_FILE_H |
| 2 | +#define __SQ_WIN32_FILE_H |
| 3 | + |
| 4 | +/** |
| 5 | + Converts multi-byte characters to wide characters. Handles paths longer |
| 6 | + than 260 characters (including NULL) by prepending "\\?\" to encode UNC |
| 7 | + paths as suggested in http://msdn.microsoft.com/en-us/library/windows/ |
| 8 | + desktop/aa365247%28v=vs.85%29.aspx#maxpath |
| 9 | + "The maximum path of 32,767 characters is approximate, |
| 10 | + because the "\\?\" prefix may be expanded to a longer |
| 11 | + string by the system at run time, and this expansion |
| 12 | + applies to the total length." |
| 13 | + |
| 14 | + Note that we do not check for the correct path component size, |
| 15 | + which should be MAX_PATH in general but can vary between file systems. |
| 16 | + Actually, we should perform an additional check with |
| 17 | + GetVolumneInformation to acquire lpMaximumComponentLength. |
| 18 | +
|
| 19 | + Note that another possibility would be to use 8.3 aliases |
| 20 | + for path components like the Windows Explorer does. However, |
| 21 | + this feature also depends on the volume specifications. |
| 22 | +
|
| 23 | + Calling alloca() should be fine because we limit path length to 32k. |
| 24 | + Stack size limit is much higher. |
| 25 | +
|
| 26 | + When using an API to create a directory, the specified path cannot be |
| 27 | + so long that you cannot append an 8.3 file name (that is, the directory |
| 28 | + name cannot exceed MAX_PATH minus 12). |
| 29 | +**/ |
| 30 | + |
| 31 | +#include <malloc.h> |
| 32 | + |
| 33 | +#define ALLOC_WIN32_PATH(out_path, in_name, in_size) { \ |
| 34 | + int sz = MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, NULL, 0); \ |
| 35 | + if(sz >= 32767) FAIL(); \ |
| 36 | + if(sz >= MAX_PATH-12 /* for directory creation; see above */) { \ |
| 37 | + out_path = (WCHAR*)alloca((sz + 4 + 1) * sizeof(WCHAR)); \ |
| 38 | + out_path[0] = L'\\'; out_path[1] = L'\\'; \ |
| 39 | + out_path[2] = L'?'; out_path[3] = L'\\'; \ |
| 40 | + MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path + 4, sz); \ |
| 41 | + out_path[sz + 4] = 0; \ |
| 42 | + } else { \ |
| 43 | + out_path = (WCHAR*)alloca((sz + 1) * sizeof(WCHAR)); \ |
| 44 | + MultiByteToWideChar(CP_UTF8, 0, in_name, in_size, out_path, sz); \ |
| 45 | + out_path[sz] = 0; \ |
| 46 | + } \ |
| 47 | +} |
| 48 | + |
| 49 | +#endif /* __SQ_WIN32_FILE_H */ |
0 commit comments