Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: content/browser/download/base_file_win.cc

Issue 11238044: Refactor BaseFile methods to return a DownloadInterruptReason instead of a net::Error. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/download/base_file.h"
6
7 #include <windows.h>
8 #include <shellapi.h>
9
10 #include "base/threading/thread_restrictions.h"
11 #include "base/utf_string_conversions.h"
12 #include "content/browser/download/download_interrupt_reasons_impl.h"
13 #include "content/browser/safe_util_win.h"
14 #include "content/public/browser/browser_thread.h"
15
16 namespace {
17
18 // Maps the result of a call to |SHFileOperation()| onto a
19 // |content::DownloadInterruptReason|.
20 //
21 // These return codes are *old* (as in, DOS era), and specific to
22 // |SHFileOperation()|.
23 // They do not appear in any windows header.
24 //
25 // See http://msdn.microsoft.com/en-us/library/bb762164(VS.85).aspx.
26 content::DownloadInterruptReason MapShFileOperationCodes(int code) {
27 // Check these pre-Win32 error codes first, then check for matches
28 // in Winerror.h.
29
30 #define SHFILE_TO_REASON(symbol, value, mapping) \
31 case value: return content::DOWNLOAD_INTERRUPT_REASON_##mapping
32
33 switch (code) {
34 // The source and destination files are the same file.
35 SHFILE_TO_REASON(DE_SAMEFILE, 0x71, FILE_FAILED);
36
37 // The operation was canceled by the user, or silently canceled if the
38 // appropriate flags were supplied to SHFileOperation.
39 SHFILE_TO_REASON(DE_OPCANCELLED, 0x75, FILE_FAILED);
40
41 // Security settings denied access to the source.
42 SHFILE_TO_REASON(DE_ACCESSDENIEDSRC, 0x78, FILE_ACCESS_DENIED);
43
44 // The source or destination path exceeded or would exceed MAX_PATH.
45 SHFILE_TO_REASON(DE_PATHTOODEEP, 0x79, FILE_NAME_TOO_LONG);
46
47 // The path in the source or destination or both was invalid.
48 SHFILE_TO_REASON(DE_INVALIDFILES, 0x7C, FILE_FAILED);
49
50 // The destination path is an existing file.
51 SHFILE_TO_REASON(DE_FLDDESTISFILE, 0x7E, FILE_FAILED);
52
53 // The destination path is an existing folder.
54 SHFILE_TO_REASON(DE_FILEDESTISFLD, 0x80, FILE_FAILED);
55
56 // The name of the file exceeds MAX_PATH.
57 SHFILE_TO_REASON(DE_FILENAMETOOLONG, 0x81, FILE_NAME_TOO_LONG);
58
59 // The destination is a read-only CD-ROM, possibly unformatted.
60 SHFILE_TO_REASON(DE_DEST_IS_CDROM, 0x82, FILE_ACCESS_DENIED);
61
62 // The destination is a read-only DVD, possibly unformatted.
63 SHFILE_TO_REASON(DE_DEST_IS_DVD, 0x83, FILE_ACCESS_DENIED);
64
65 // The destination is a writable CD-ROM, possibly unformatted.
66 SHFILE_TO_REASON(DE_DEST_IS_CDRECORD, 0x84, FILE_ACCESS_DENIED);
67
68 // The file involved in the operation is too large for the destination
69 // media or file system.
70 SHFILE_TO_REASON(DE_FILE_TOO_LARGE, 0x85, FILE_TOO_LARGE);
71
72 // The source is a read-only CD-ROM, possibly unformatted.
73 SHFILE_TO_REASON(DE_SRC_IS_CDROM, 0x86, FILE_ACCESS_DENIED);
74
75 // The source is a read-only DVD, possibly unformatted.
76 SHFILE_TO_REASON(DE_SRC_IS_DVD, 0x87, FILE_ACCESS_DENIED);
77
78 // The source is a writable CD-ROM, possibly unformatted.
79 SHFILE_TO_REASON(DE_SRC_IS_CDRECORD, 0x88, FILE_ACCESS_DENIED);
80
81 // MAX_PATH was exceeded during the operation.
82 SHFILE_TO_REASON(DE_ERROR_MAX, 0xB7, FILE_NAME_TOO_LONG);
83
84 // An unspecified error occurred on the destination.
85 SHFILE_TO_REASON(XE_ERRORONDEST, 0x10000, FILE_FAILED);
86
87 // Multiple file paths were specified in the source buffer, but only one
88 // destination file path.
89 SHFILE_TO_REASON(DE_MANYSRC1DEST, 0x72, FILE_FAILED);
90
91 // Rename operation was specified but the destination path is
92 // a different directory. Use the move operation instead.
93 SHFILE_TO_REASON(DE_DIFFDIR, 0x73, FILE_FAILED);
94
95 // The source is a root directory, which cannot be moved or renamed.
96 SHFILE_TO_REASON(DE_ROOTDIR, 0x74, FILE_FAILED);
97
98 // The destination is a subtree of the source.
99 SHFILE_TO_REASON(DE_DESTSUBTREE, 0x76, FILE_FAILED);
100
101 // The operation involved multiple destination paths,
102 // which can fail in the case of a move operation.
103 SHFILE_TO_REASON(DE_MANYDEST, 0x7A, FILE_FAILED);
104
105 // The source and destination have the same parent folder.
106 SHFILE_TO_REASON(DE_DESTSAMETREE, 0x7D, FILE_FAILED);
107
108 // An unknown error occurred. This is typically due to an invalid path in
109 // the source or destination. This error does not occur on Windows Vista
110 // and later.
111 SHFILE_TO_REASON(DE_UNKNOWN_ERROR, 0x402, FILE_FAILED);
112
113 // Destination is a root directory and cannot be renamed.
114 SHFILE_TO_REASON(DE_ROOTDIR | ERRORONDEST, 0x10074, FILE_FAILED);
115 }
116
117 #undef SHFILE_TO_REASON
118
119 // If not one of the above codes, it should be a standard Windows error code.
120 return content::ConvertNetErrorToInterruptReason(
121 net::MapSystemError(code), content::DOWNLOAD_INTERRUPT_FROM_DISK);
122 }
123
124 } // namespace
125
126 // Renames a file using the SHFileOperation API to ensure that the target file
127 // gets the correct default security descriptor in the new path.
128 // Returns a network error, or net::OK for success.
129 content::DownloadInterruptReason BaseFile::MoveFileAndAdjustPermissions(
130 const FilePath& new_path) {
131 base::ThreadRestrictions::AssertIOAllowed();
132
133 // The parameters to SHFileOperation must be terminated with 2 NULL chars.
134 FilePath::StringType source = full_path_.value();
135 FilePath::StringType target = new_path.value();
136
137 source.append(1, L'\0');
138 target.append(1, L'\0');
139
140 SHFILEOPSTRUCT move_info = {0};
141 move_info.wFunc = FO_MOVE;
142 move_info.pFrom = source.c_str();
143 move_info.pTo = target.c_str();
144 move_info.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI |
145 FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS;
146
147 int result = SHFileOperation(&move_info);
148 content::DownloadInterruptReason interrupt_reason =
149 content::DOWNLOAD_INTERRUPT_REASON_NONE;
150
151 if (result == 0 && move_info.fAnyOperationsAborted)
152 interrupt_reason = content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
153 else if (result != 0)
154 interrupt_reason = MapShFileOperationCodes(result);
155
156 if (interrupt_reason != content::DOWNLOAD_INTERRUPT_REASON_NONE)
157 return LogInterruptReason("SHFileOperation", result, interrupt_reason);
158 return interrupt_reason;
159 }
160
161 content::DownloadInterruptReason BaseFile::AnnotateWithSourceInformation() {
162 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
163 DCHECK(!detached_);
164
165 // Sets the Zone to tell Windows that this file comes from the internet.
166 // We ignore the return value because a failure is not fatal.
167 win_util::SetInternetZoneIdentifier(full_path_,
168 UTF8ToWide(source_url_.spec()));
169 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
170 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698