1067
gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft);
1089
/* skip restoring time stamps on user's request */
1090
if (uO.D_flag <= 1) {
1091
gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft);
1069
/* open a handle to the file before processing extra fields;
1070
we do this in case new security on file prevents us from updating
1072
hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
1073
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1093
/* open a handle to the file before processing extra fields;
1094
we do this in case new security on file prevents us from updating
1096
hFile = CreateFileA(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
1097
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1075
1102
/* sfield@microsoft.com: set attributes before time in case we decide to
1076
1103
support other filetime members later. This also allows us to apply
1107
1134
#endif /* NTSD_EAS */
1109
if ( hFile == INVALID_HANDLE_VALUE )
1110
Info(slide, 1, ((char *)slide,
1111
"\nCreateFile() error %d when trying set file time\n",
1112
(int)GetLastError()));
1115
FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL;
1116
FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL;
1117
FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL;
1136
/* skip restoring time stamps on user's request */
1137
if (uO.D_flag <= 1) {
1138
if ( hFile == INVALID_HANDLE_VALUE )
1139
Info(slide, 1, ((char *)slide,
1140
"\nCreateFile() error %d when trying set file time\n",
1141
(int)GetLastError()));
1144
FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL;
1145
FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL;
1146
FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL;
1119
if (!SetFileTime(hFile, pCreft, pAccft, pModft))
1120
Info(slide, 0, ((char *)slide, "\nSetFileTime failed: %d\n",
1121
(int)GetLastError()));
1148
if (!SetFileTime(hFile, pCreft, pAccft, pModft))
1149
Info(slide, 0, ((char *)slide,
1150
"\nSetFileTime failed: %d\n", (int)GetLastError()));
1215
1247
# define Ansi_Dirname d->fn
1218
/* Open a handle to the directory before processing extra fields;
1219
we do this in case new security on file prevents us from updating
1221
Although the WIN32 documentation recommends to use GENERIC_WRITE
1222
access flag to create the handle for SetFileTime(), this is too
1223
demanding for directories with the "read-only" attribute bit set.
1224
So we use the more specific flag FILE_WRITE_ATTRIBUTES here to
1225
request the minimum required access rights. (This problem is a
1226
Windows bug that has been silently fixed in Windows XP SP2.) */
1227
hFile = CreateFile(Ansi_Dirname, FILE_WRITE_ATTRIBUTES,
1228
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
1229
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1250
/* Skip restoring directory time stamps on user' request. */
1251
if (uO.D_flag <= 0) {
1252
/* Open a handle to the directory before processing extra fields;
1253
we do this in case new security on file prevents us from updating
1255
Although the WIN32 documentation recommends to use GENERIC_WRITE
1256
access flag to create the handle for SetFileTime(), this is too
1257
demanding for directories with the "read-only" attribute bit set.
1258
So we use the more specific flag FILE_WRITE_ATTRIBUTES here to
1259
request the minimum required access rights. (This problem is a
1260
Windows bug that has been silently fixed in Windows XP SP2.) */
1261
hFile = CreateFileA(Ansi_Dirname, FILE_WRITE_ATTRIBUTES,
1262
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
1263
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1231
1266
#ifdef NTSD_EAS
1232
1267
if (NtAtt(d)->SDlen > 0) {
1255
1290
#endif /* NTSD_EAS */
1257
if (hFile == INVALID_HANDLE_VALUE) {
1258
Info(slide, 1, ((char *)slide,
1259
"warning: CreateFile() error %d (set file times for %s)\n",
1260
(int)GetLastError(), FnFilter1(d->fn)));
1264
if (NtAtt(d)->gotTime) {
1265
FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME)
1266
? &(NtAtt(d)->Modft) : NULL;
1267
FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME)
1268
? &(NtAtt(d)->Accft) : NULL;
1269
FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME)
1270
? &(NtAtt(d)->Creft) : NULL;
1292
/* Skip restoring directory time stamps on user' request. */
1293
if (uO.D_flag <= 0) {
1294
if (hFile == INVALID_HANDLE_VALUE) {
1295
Info(slide, 1, ((char *)slide,
1296
"warning: CreateFile() error %d (set file times for %s)\n",
1297
(int)GetLastError(), FnFilter1(d->fn)));
1301
if (NtAtt(d)->gotTime) {
1302
FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME)
1303
? &(NtAtt(d)->Modft) : NULL;
1304
FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME)
1305
? &(NtAtt(d)->Accft) : NULL;
1306
FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME)
1307
? &(NtAtt(d)->Creft) : NULL;
1272
if (!SetFileTime(hFile, pCreft, pAccft, pModft)) {
1273
Info(slide, 0, ((char *)slide,
1274
"warning: SetFileTime() for %s error %d\n",
1275
FnFilter1(d->fn), (int)GetLastError()));
1309
if (!SetFileTime(hFile, pCreft, pAccft, pModft)) {
1310
Info(slide, 0, ((char *)slide,
1311
"warning: SetFileTime() for %s error %d\n",
1312
FnFilter1(d->fn), (int)GetLastError()));
2227
2271
int error = MPN_OK;
2229
2273
Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
2274
/* The buildpathHPFS buffer has been allocated large enough to
2275
* hold the complete combined name, so there is no need to check
2276
* for OS filename size limit overflow within the copy loop.
2230
2278
while ((*G.endHPFS = *p++) != '\0') { /* copy to HPFS filename */
2232
if ((G.endHPFS-G.buildpathHPFS) >= FILNAMSIZ) {
2233
*--G.endHPFS = '\0';
2234
Info(slide, 1, ((char *)slide,
2235
"checkdir warning: path too long; truncating\n \
2237
FnFilter1(G.filename), FnFilter2(G.buildpathHPFS)));
2238
error = MPN_INF_TRUNC; /* filename truncated */
2281
/* Now, check for OS filename size overflow. When detected, the
2282
* mapped HPFS name is truncated and a warning message is shown.
2284
if ((G.endHPFS-G.buildpathHPFS) >= FILNAMSIZ) {
2285
G.buildpathHPFS[FILNAMSIZ-1] = '\0';
2286
Info(slide, 1, ((char *)slide,
2287
"checkdir warning: path too long; truncating\n \
2289
FnFilter1(G.filename), FnFilter2(G.buildpathHPFS)));
2290
error = MPN_INF_TRUNC; /* filename truncated */
2242
if ( G.pInfo->vollabel || !IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
2293
/* The buildpathFAT buffer has the same allocated size as the
2294
* buildpathHPFS buffer, so there is no need for an overflow check
2295
* within the following copy loop, either.
2297
if (G.pInfo->vollabel || !IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
2298
/* copy to FAT filename, too */
2244
while ((*G.endFAT = *p++) != '\0') /* copy to FAT filename, too */
2300
while ((*G.endFAT = *p++) != '\0')
2247
map2fat(pathcomp, &G.endFAT); /* map into FAT fn, update endFAT */
2303
/* map into FAT fn, update endFAT */
2304
map2fat(pathcomp, &G.endFAT);
2306
/* Check that the FAT path does not exceed the FILNAMSIZ limit, and
2307
* truncate when neccessary.
2308
* Note that truncation can only happen when the HPFS path (which is
2309
* never shorter than the FAT path) has been already truncated.
2310
* So, emission of the warning message and setting the error code
2311
* has already happened.
2313
if ((G.endFAT-G.buildpathFAT) >= FILNAMSIZ)
2314
G.buildpathFAT[FILNAMSIZ-1] = '\0';
2248
2315
Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT: %s\n",
2249
2316
FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT)));
2667
2734
TTrace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime));
2668
h = CreateFile(Ansi_Path, GENERIC_READ,
2669
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2670
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2735
h = CreateFileA(Ansi_Path, GENERIC_READ,
2736
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2737
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2671
2738
if (h != INVALID_HANDLE_VALUE) {
2672
2739
BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
2673
2740
CloseHandle(h);
2876
2943
#endif /* !WINDLL */
2947
#if (defined(UNICODE_SUPPORT) && !defined(FUNZIP))
2948
/* convert wide character string to multi-byte character string */
2949
char *wide_to_local_string(wide_string, escape_all)
2950
ZCONST zwchar *wide_string;
2960
char *buffer = NULL;
2961
char *local_string = NULL;
2963
for (wsize = 0; wide_string[wsize]; wsize++) ;
2965
if (max_bytes < MB_CUR_MAX)
2966
max_bytes = MB_CUR_MAX;
2968
if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) {
2974
for (i = 0; i < wsize; i++) {
2975
if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) {
2976
/* wchar_t probably 2 bytes */
2977
/* could do surrogates if state_dependent and wctomb can do */
2978
wc = zwchar_to_wchar_t_default_char;
2980
wc = (wchar_t)wide_string[i];
2982
/* Unter some vendor's C-RTL, the Wide-to-MultiByte conversion functions
2983
* (like wctomb() et. al.) do not use the same codepage as the other
2984
* string arguments I/O functions (fopen, mkdir, rmdir etc.).
2985
* Therefore, we have to fall back to the underlying Win32-API call to
2986
* achieve a consistent behaviour for all supported compiler environments.
2987
* Failing RTLs are for example:
2988
* Borland (locale uses OEM-CP as default, but I/O functions expect ANSI
2990
* Watcom (only "C" locale, wctomb() always uses OEM CP)
2991
* (in other words: all supported environments except the Microsoft RTLs)
2993
bytes_char = WideCharToMultiByte(
2994
CP_ACP, WC_COMPOSITECHECK,
2996
(LPSTR)buf, sizeof(buf),
2997
NULL, &default_used);
3001
if (bytes_char == 1 && (uch)buf[0] <= 0x7f) {
3003
strncat(buffer, buf, 1);
3005
/* use escape for wide character */
3006
char *escape_string = wide_to_escape_string(wide_string[i]);
3007
strcat(buffer, escape_string);
3008
free(escape_string);
3010
} else if (bytes_char > 0) {
3011
/* multi-byte char */
3012
strncat(buffer, buf, bytes_char);
3014
/* no MB for this wide */
3015
/* use escape for wide character */
3016
char *escape_string = wide_to_escape_string(wide_string[i]);
3017
strcat(buffer, escape_string);
3018
free(escape_string);
3021
if ((local_string = (char *)realloc(buffer, strlen(buffer) + 1)) == NULL) {
3026
return local_string;
3031
wchar_t *utf8_to_wchar_string(utf8_string)
3032
char *utf8_string; /* path to get utf-8 name for */
3038
if (utf8_string == NULL)
3042
ulenw = MultiByteToWideChar(
3043
CP_UTF8, /* UTF-8 code page */
3044
0, /* flags for character-type options */
3045
utf8_string, /* string to convert */
3046
-1, /* string length (-1 = NULL terminated) */
3048
0 ); /* buffer length (0 = return length) */
3054
/* get length in bytes */
3055
ulen = sizeof(wchar_t) * (ulenw + 1);
3056
if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
3059
/* convert multibyte to wide */
3060
ulen = MultiByteToWideChar(
3061
CP_UTF8, /* UTF-8 code page */
3062
0, /* flags for character-type options */
3063
utf8_string, /* string to convert */
3064
-1, /* string length (-1 = NULL terminated) */
3066
ulenw); /* buffer length (0 = return length) */
3076
wchar_t *local_to_wchar_string(local_string)
3077
char *local_string; /* path of local name */
3083
if (local_string == NULL)
3087
ulenw = MultiByteToWideChar(
3088
CP_ACP, /* ANSI code page */
3089
0, /* flags for character-type options */
3090
local_string, /* string to convert */
3091
-1, /* string length (-1 = NULL terminated) */
3093
0 ); /* buffer length (0 = return length) */
3099
/* get length in bytes */
3100
ulen = sizeof(wchar_t) * (ulenw + 1);
3101
if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
3104
/* convert multibyte to wide */
3105
ulen = MultiByteToWideChar(
3106
CP_ACP, /* ANSI code page */
3107
0, /* flags for character-type options */
3108
local_string, /* string to convert */
3109
-1, /* string length (-1 = NULL terminated) */
3111
ulenw); /* buffer length (0 = return length) */
3121
#endif /* UNICODE_SUPPORT && !FUNZIP */
3125
/* --------------------------------------------------- */
3126
/* Large File Support
3128
* Initial functions by E. Gordon and R. Nausedat
3130
* Lifted from Zip 3b, win32.c and place here by Myles Bennett
3133
* These implement 64-bit file support for Windows. The
3134
* defines and headers are in win32/w32cfg.h.
3136
* Moved to win32i64.c by Mike White to avoid conflicts in
3137
* same name functions in WiZ using UnZip and Zip libraries.