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

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: Remove SHFILE_TO_REASON macro Created 8 years, 2 months 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 switch (code) {
31 // The source and destination files are the same file.
32 // DE_SAMEFILE == 0x71
33 case 0x71: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
34
35 // The operation was canceled by the user, or silently canceled if the
36 // appropriate flags were supplied to SHFileOperation.
37 // DE_OPCANCELLED == 0x75
38 case 0x75: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
39
40 // Security settings denied access to the source.
41 // DE_ACCESSDENIEDSRC == 0x78
42 case 0x78: return content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
43
44 // The source or destination path exceeded or would exceed MAX_PATH.
45 // DE_PATHTOODEEP == 0x79
46 case 0x79: return content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG;
47
48 // The path in the source or destination or both was invalid.
49 // DE_INVALIDFILES == 0x7C
50 case 0x7C: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
51
52 // The destination path is an existing file.
53 // DE_FLDDESTISFILE == 0x7E
54 case 0x7E: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
55
56 // The destination path is an existing folder.
57 // DE_FILEDESTISFLD == 0x80
58 case 0x80: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
59
60 // The name of the file exceeds MAX_PATH.
61 // DE_FILENAMETOOLONG == 0x81
62 case 0x81: return content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG;
63
64 // The destination is a read-only CD-ROM, possibly unformatted.
65 // DE_DEST_IS_CDROM == 0x82
66 case 0x82: return content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
67
68 // The destination is a read-only DVD, possibly unformatted.
69 // DE_DEST_IS_DVD == 0x83
70 case 0x83: return content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
71
72 // The destination is a writable CD-ROM, possibly unformatted.
73 // DE_DEST_IS_CDRECORD == 0x84
74 case 0x84: return content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
75
76 // The file involved in the operation is too large for the destination
77 // media or file system.
78 // DE_FILE_TOO_LARGE == 0x85
79 case 0x85: return content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE;
80
81 // The source is a read-only CD-ROM, possibly unformatted.
82 // DE_SRC_IS_CDROM == 0x86
83 case 0x86: return content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
84
85 // The source is a read-only DVD, possibly unformatted.
86 // DE_SRC_IS_DVD == 0x87
87 case 0x87: return content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
88
89 // The source is a writable CD-ROM, possibly unformatted.
90 // DE_SRC_IS_CDRECORD == 0x88
91 case 0x88: return content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
92
93 // MAX_PATH was exceeded during the operation.
94 // DE_ERROR_MAX == 0xB7
95 case 0xB7: return content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG;
96
97 // An unspecified error occurred on the destination.
98 // XE_ERRORONDEST == 0x10000
99 case 0x10000: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
100
101 // Multiple file paths were specified in the source buffer, but only one
102 // destination file path.
103 // DE_MANYSRC1DEST == 0x72
104 case 0x72: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
105
106 // Rename operation was specified but the destination path is
107 // a different directory. Use the move operation instead.
108 // DE_DIFFDIR == 0x73
109 case 0x73: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
110
111 // The source is a root directory, which cannot be moved or renamed.
112 // DE_ROOTDIR == 0x74
113 case 0x74: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
114
115 // The destination is a subtree of the source.
116 // DE_DESTSUBTREE == 0x76
117 case 0x76: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
118
119 // The operation involved multiple destination paths,
120 // which can fail in the case of a move operation.
121 // DE_MANYDEST == 0x7A
122 case 0x7A: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
123
124 // The source and destination have the same parent folder.
125 // DE_DESTSAMETREE == 0x7D
126 case 0x7D: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
127
128 // An unknown error occurred. This is typically due to an invalid path in
129 // the source or destination. This error does not occur on Windows Vista
130 // and later.
131 // DE_UNKNOWN_ERROR == 0x402
132 case 0x402: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
133
134 // Destination is a root directory and cannot be renamed.
135 // DE_ROOTDIR | ERRORONDEST == 0x10074
136 case 0x10074: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
137 }
138
139 // If not one of the above codes, it should be a standard Windows error code.
140 return content::ConvertNetErrorToInterruptReason(
141 net::MapSystemError(code), content::DOWNLOAD_INTERRUPT_FROM_DISK);
142 }
143
144 } // namespace
145
146 // Renames a file using the SHFileOperation API to ensure that the target file
147 // gets the correct default security descriptor in the new path.
148 // Returns a network error, or net::OK for success.
149 content::DownloadInterruptReason BaseFile::MoveFileAndAdjustPermissions(
150 const FilePath& new_path) {
151 base::ThreadRestrictions::AssertIOAllowed();
152
153 // The parameters to SHFileOperation must be terminated with 2 NULL chars.
154 FilePath::StringType source = full_path_.value();
155 FilePath::StringType target = new_path.value();
156
157 source.append(1, L'\0');
158 target.append(1, L'\0');
159
160 SHFILEOPSTRUCT move_info = {0};
161 move_info.wFunc = FO_MOVE;
162 move_info.pFrom = source.c_str();
163 move_info.pTo = target.c_str();
164 move_info.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI |
165 FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS;
166
167 int result = SHFileOperation(&move_info);
168 content::DownloadInterruptReason interrupt_reason =
169 content::DOWNLOAD_INTERRUPT_REASON_NONE;
170
171 if (result == 0 && move_info.fAnyOperationsAborted)
172 interrupt_reason = content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
173 else if (result != 0)
174 interrupt_reason = MapShFileOperationCodes(result);
175
176 if (interrupt_reason != content::DOWNLOAD_INTERRUPT_REASON_NONE)
177 return LogInterruptReason("SHFileOperation", result, interrupt_reason);
178 return interrupt_reason;
179 }
180
181 void BaseFile::AnnotateWithSourceInformation() {
182 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
183 DCHECK(!detached_);
184
185 // Sets the Zone to tell Windows that this file comes from the internet.
186 // We ignore the return value because a failure is not fatal.
187 win_util::SetInternetZoneIdentifier(full_path_,
188 UTF8ToWide(source_url_.spec()));
189 }
OLDNEW
« no previous file with comments | « content/browser/download/base_file_unittest.cc ('k') | content/browser/download/download_file_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698