To: vim-dev@vim.org Subject: Patch 6.1.151 (extra) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.1.151 (extra) Problem: Win32: The NTFS substream isn't copied. Solution: Copy the substream when making a backup copy. (Muraoka Taro) Files: src/fileio.c, src/os_win32.c, src/proto/os_win32.pro *** ../vim61.150/src/fileio.c Sun Jun 23 15:00:56 2002 --- src/fileio.c Sun Aug 4 22:00:33 2002 *************** *** 3290,3296 **** } errmsg = NULL; ! #ifdef MACOS_CLASSIC /* TODO: Is it need for MACOS_X? (Dany) */ /* * On macintosh copy the original files attributes (i.e. the backup) * This is done in order to preserve the ressource fork and the --- 3291,3298 ---- } errmsg = NULL; ! #if defined(MACOS_CLASSIC) || defined(WIN3264) ! /* TODO: Is it need for MACOS_X? (Dany) */ /* * On macintosh copy the original files attributes (i.e. the backup) * This is done in order to preserve the ressource fork and the *** ../vim61.150/src/os_win32.c Sun Aug 4 21:03:47 2002 --- src/os_win32.c Sun Aug 4 22:04:32 2002 *************** *** 4031,4034 **** --- 4039,4148 ---- return -1; CloseHandle(hFile); return 0; + } + + /* + * SUB STREAM: + * + * NTFS can have sub streams for each file. Normal contents of file is + * stored in main stream, and external contents (author information and + * title and so on) can be stored in sub stream. After Windows 2000, user + * can access and store those informations in sub streams via explorer's + * property menuitem in right click menu. Those informations in sub streams + * were lost when copy only main streams. So we have to copy sub streams. + * + * http://msdn.microsoft.com/library/en-us/dnw2k/html/ntfs5.asp + */ + + static char * + get_infostream_name(char *name, char *substream) + { + int len; + char *newname; + + len = strlen(name) + strlen(substream) + 2; + newname = malloc(len); + strcpy(newname, name); + strcat(newname, ":"); + strcat(newname, substream); + return newname; + } + + static int + copy_substream(char *from, char *to, char *substream) + { + int retval = 0; + HANDLE hFrom, hTo; + char *from_info, *to_info; + + from_info = get_infostream_name(from, substream); + to_info = get_infostream_name(to, substream); + hFrom = CreateFile(from_info, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + hTo = CreateFile(to_info, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFrom != INVALID_HANDLE_VALUE && hTo != INVALID_HANDLE_VALUE) + { + /* Just copy information */ + DWORD dwCopy, dwSize, dwRead = 0, dwWrite = 0; + char buf[4096]; + + retval = 1; + dwCopy = GetFileSize(hFrom, NULL); + while (dwCopy > 0) + { + dwSize = dwCopy > sizeof(buf) ? sizeof(buf) : dwCopy; + if (!ReadFile(hFrom, buf, dwSize, &dwRead, NULL) + || dwRead != dwSize + || !WriteFile(hTo, buf, dwSize, &dwWrite, NULL) + || dwWrite != dwSize) + { + retval = 0; + break; + } + dwCopy -= dwSize; + } + } + else if (hFrom == INVALID_HANDLE_VALUE && hTo != INVALID_HANDLE_VALUE) + { + /* No source information, delete destination */ + CloseHandle(hTo); + hTo = INVALID_HANDLE_VALUE; + retval = DeleteFile(to_info); + retval = 1; + } + else if (hFrom == INVALID_HANDLE_VALUE && hTo == INVALID_HANDLE_VALUE) + { + retval = 1; + } + + if (hFrom != INVALID_HANDLE_VALUE) + CloseHandle(hFrom); + if (hTo != INVALID_HANDLE_VALUE) + CloseHandle(hTo); + free(from_info); + free(to_info); + + return 1; + } + + static int + copy_infostreams(char_u *from, char_u *to) + { + if (!copy_substream(from, to, "\05SummaryInformation")) + goto FAILTOCOPY; + if (!copy_substream(from, to, "\05DocumentSummaryInformation")) + goto FAILTOCOPY; + if (!copy_substream(from, to, "\05SebiesnrMkudrfcoIaamtykdDa")) + goto FAILTOCOPY; + return 1; + FAILTOCOPY: + return 0; + } + + int + mch_copy_file_attribute(char_u *from, char_u *to) + { + return copy_infostreams(from, to); } *** ../vim61.150/src/proto/os_win32.pro Fri Mar 22 21:41:32 2002 --- src/proto/os_win32.pro Sun Aug 4 22:05:14 2002 *************** *** 43,46 **** --- 43,47 ---- int mch_rename __ARGS((const char *pszOldFile, const char *pszNewFile)); char *default_shell __ARGS((void)); int mch_access __ARGS((char *n, int p)); + int mch_copy_file_attribute __ARGS((char_u *from, char_u *to)); /* vim: set ft=c : */ *** ../vim61.150/src/version.c Sun Aug 4 21:51:53 2002 --- src/version.c Sun Aug 4 22:12:01 2002 *************** *** 608,609 **** --- 608,611 ---- { /* Add new patch number below this line */ + /**/ + 151, /**/ -- hundred-and-one symptoms of being an internet addict: 94. Now admit it... How many of you have made "modem noises" into the phone just to see if it was possible? :-) /// Bram Moolenaar -- Bram@moolenaar.net -- http://www.moolenaar.net \\\ /// Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim \\\ \\\ Project leader for A-A-P -- http://www.a-a-p.org /// \\\ Lord Of The Rings helps Uganda - http://iccf-holland.org/lotr.html ///