Hello nigeltao,
I'd like you to do a code review. Please execute
g4 diff -c 11153982
or point your web browser to
http://mondrian/11153982
(this changelist has been uploaded to Mondrian)
to review the following code:
Change 11153982 by n...@noel-gears on 2009/05/15 21:42:22 *pending*
Follow links and resolve file attributes of drop files.
PRESUBMIT=passed
R=nigeltao
[email protected]
DELTA=126 (90 added, 3 deleted, 33 changed)
OCL=11153982
Affected files ...
...
//depot/googleclient/gears/opensource/gears/desktop/drag_and_drop_utils_ie.cc#15
edit
126 delta lines: 90 added, 3 deleted, 33 changed
Also consider running:
g4 lint -c 11153982
which verifies that the changelist doesn't introduce new style violations.
If you can't do the review, please let me know as soon as possible. During
your review, please ensure that all new code has corresponding unit tests and
that existing unit tests are updated appropriately. Visit
http://www/eng/code_review.html for more information.
This is a semiautomated message from "g4 mail". Complaints or suggestions?
Mail [email protected].
Change 11153982 by n...@noel-gears on 2009/05/15 21:42:22 *pending*
Follow links and resolve file attributes of drop files.
Affected files ...
...
//depot/googleclient/gears/opensource/gears/desktop/drag_and_drop_utils_ie.cc#15
edit
====
//depot/googleclient/gears/opensource/gears/desktop/drag_and_drop_utils_ie.cc#15
-
c:\Users\noel.GOOGLE\src-gears/googleclient/gears/opensource/gears/desktop/drag_and_drop_utils_ie.cc
====
# action=edit type=text
--- googleclient/gears/opensource/gears/desktop/drag_and_drop_utils_ie.cc
2009-05-15 21:43:00.000000000 +1000
+++ googleclient/gears/opensource/gears/desktop/drag_and_drop_utils_ie.cc
2009-05-15 21:42:12.000000000 +1000
@@ -35,31 +35,115 @@
#include "gears/base/ie/activex_utils.h"
#include "gears/desktop/drag_and_drop_utils_win32.h"
-
-// This function overwrites buffer in-place.
-static HRESULT ResolveShortcut(TCHAR *buffer) {
- static CComPtr<IShellLink> link;
- if (!link && FAILED(link.CoCreateInstance(CLSID_ShellLink))) {
- return E_FAIL;
- }
-
- CComQIPtr<IPersistFile> file(link);
- if (!file) return E_FAIL;
-
- // Open the shortcut file, load its content.
- HRESULT hr = file->Load(buffer, STGM_READ);
- if (FAILED(hr)) return hr;
-
- // Resolve the target of the shortcut.
- hr = link->Resolve(NULL, SLR_NO_UI);
- if (FAILED(hr)) return hr;
-
- // Read the target path.
- hr = link->GetPath(buffer, MAX_PATH, 0, SLGP_UNCPRIORITY);
- if (FAILED(hr)) return hr;
-
- return S_OK;
-}
+class FileAttributes {
+ public:
+ explicit FileAttributes(const std::string16 &path) {
+ if (!::lstrcpyn(path_, path.c_str(), MAX_PATH))
+ path_[0] = static_cast<WCHAR>(0); // assumption: path_[MAX_PATH]
+ ResolvePath(path_);
+ }
+
+ bool Found() const {
+ if (find_handle_ != INVALID_HANDLE_VALUE)
+ return attributes_ & SFGAO_CANCOPY;
+ return false;
+ }
+
+ bool IsDirectory() const {
+ return !!(file_find_data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+ }
+
+ ULONGLONG GetFileSize() const {
+ const ULARGE_INTEGER size =
+ { file_find_data_.nFileSizeLow, file_find_data_.nFileSizeHigh };
+ return size.QuadPart;
+ }
+
+ const WCHAR *GetBaseName() const {
+ return file_find_data_.cFileName;
+ }
+
+ const WCHAR *GetFileExtension() const {
+ return ::PathFindExtension(GetBaseName());
+ }
+
+ const WCHAR *GetFilePath() const {
+ return path_;
+ }
+
+ ~FileAttributes() {
+ ::FindClose(find_handle_);
+ }
+
+ private:
+ void ResolvePath(WCHAR *path) {
+ LOG16((L"%s\n", path));
+
+ find_handle_ = ::FindFirstFile(path, &file_find_data_);
+ attributes_ = 0;
+
+ if (find_handle_ != INVALID_HANDLE_VALUE) {
+ if (ResolveAttributes(path)) {
+ ResolveLinks(path);
+ } else {
+ ::FindClose(find_handle_);
+ find_handle_ = INVALID_HANDLE_VALUE;
+ attributes_ = 0;
+ }
+ }
+ }
+
+ DWORD ResolveAttributes(const WCHAR *path) {
+ SHFILEINFO info;
+ if (::SHGetFileInfo(path, 0, &info, sizeof(info), SHGFI_ATTRIBUTES))
+ return (attributes_ = info.dwAttributes) & SFGAO_FILESYSTEM;
+ return attributes_ = 0;
+ }
+
+ void ResolveLinks(WCHAR *path) {
+ if (attributes_ & SFGAO_LINK) {
+ if (FAILED(ResolveShortcut(path, path))) {
+ LOG16((L" link resolve failed\n"));
+ } else {
+ ::FindClose(find_handle_);
+ ResolvePath(path);
+ }
+ }
+ }
+
+ static HRESULT ResolveShortcut(const WCHAR *shortcut, WCHAR *target) {
+ LOG16((L" resolving %s\n", shortcut));
+
+ static CComPtr<IShellLink> link;
+ if (!link && FAILED(link.CoCreateInstance(CLSID_ShellLink)))
+ return E_FAIL;
+
+ static CComQIPtr<IPersistFile> file(link);
+ if (!file) return E_FAIL;
+
+ // Open the shortcut file, load its content.
+ HRESULT hr = file->Load(shortcut, STGM_READ);
+ if (FAILED(hr)) return hr;
+
+ // Resolve the target of the shortcut.
+ // hr = link->Resolve(NULL, SLR_NO_UI);
+ // if (FAILED(hr)) return hr;
+
+ // Get the shortcut target path.
+ hr = link->GetPath(target, MAX_PATH, 0, SLGP_UNCPRIORITY);
+ if (FAILED(hr)) return hr;
+
+ return S_OK;
+ }
+
+ private:
+ WCHAR path_[MAX_PATH];
+ WIN32_FIND_DATA file_find_data_;
+ HANDLE find_handle_;
+ DWORD attributes_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(FileAttributes);
+};
HRESULT GetHtmlDataTransfer(
@@ -113,24 +197,27 @@
UINT num_files = DragQueryFile(hdrop, -1, 0, 0);
WCHAR buffer[MAX_PATH];
for (UINT i = 0; i < num_files; ++i) {
- DragQueryFile(hdrop, i, buffer, MAX_PATH);
- SHFILEINFO sh_file_info;
- if (!SHGetFileInfo(buffer, 0, &sh_file_info, sizeof(sh_file_info),
- SHGFI_ATTRIBUTES) ||
- !(sh_file_info.dwAttributes & SFGAO_FILESYSTEM) ||
- (sh_file_info.dwAttributes & SFGAO_FOLDER)) {
- continue;
+ if (!DragQueryFile(hdrop, i, buffer, MAX_PATH)) {
+ GlobalUnlock(stg_medium.hGlobal);
+ ReleaseStgMedium(&stg_medium);
+ return false;
}
- if ((sh_file_info.dwAttributes & SFGAO_LINK) &&
- FAILED(ResolveShortcut(buffer))) {
- continue;
+
+ std::string16 path(buffer);
+ FileAttributes attributes(path);
+ if (!attributes.Found() || attributes.IsDirectory()) {
+ GlobalUnlock(stg_medium.hGlobal);
+ ReleaseStgMedium(&stg_medium);
+ return false;
}
- filenames.push_back(std::string16(buffer));
+
+ filenames.push_back(attributes.GetFilePath());
}
GlobalUnlock(stg_medium.hGlobal);
ReleaseStgMedium(&stg_medium);
}
+
meta_data_out->SetFilenames(filenames);
return true;
}