diff options
25 files changed, 869 insertions, 802 deletions
diff --git a/app/win_util.h b/app/win_util.h index 2aecea5..34c2586 100644 --- a/app/win_util.h +++ b/app/win_util.h @@ -23,7 +23,6 @@ namespace win_util { // Import ScopedHandle and friends into this namespace for backwards // compatibility. TODO(darin): clean this up! using ::ScopedHandle; -using ::ScopedFindFileHandle; using ::ScopedHDC; using ::ScopedBitmap; diff --git a/base/base.gyp b/base/base.gyp index d6245ca..dee0040 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -124,12 +124,9 @@ 'rand_util_unittest.cc', 'ref_counted_unittest.cc', 'registry_unittest.cc', - 'scoped_bstr_win_unittest.cc', - 'scoped_comptr_win_unittest.cc', 'scoped_native_library_unittest.cc', 'scoped_ptr_unittest.cc', 'scoped_temp_dir_unittest.cc', - 'scoped_variant_win_unittest.cc', 'sha1_unittest.cc', 'sha2_unittest.cc', 'shared_memory_unittest.cc', @@ -168,6 +165,9 @@ 'watchdog_unittest.cc', 'weak_ptr_unittest.cc', 'win_util_unittest.cc', + 'win/scoped_bstr_unittest.cc', + 'win/scoped_comptr_unittest.cc', + 'win/scoped_variant_unittest.cc', 'worker_pool_unittest.cc', ], 'include_dirs': [ @@ -213,6 +213,9 @@ 'file_descriptor_shuffle_unittest.cc', ], }, { # OS != "win" + 'sources/': [ + ['exclude', '^win/'], + ], 'sources!': [ 'event_trace_consumer_win_unittest.cc', 'event_trace_controller_win_unittest.cc', diff --git a/base/base.gypi b/base/base.gypi index 20223bb..fee14af 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -196,13 +196,9 @@ 'safe_strerror_posix.cc', 'safe_strerror_posix.h', 'scoped_aedesc.h', - 'scoped_bstr_win.cc', - 'scoped_bstr_win.h', 'scoped_callback_factory.h', 'scoped_cftyperef.h', - 'scoped_comptr_win.h', 'scoped_handle.h', - 'scoped_handle_win.h', 'scoped_nsautorelease_pool.h', 'scoped_nsautorelease_pool.mm', 'scoped_nsdisable_screen_updates.h', @@ -211,8 +207,6 @@ 'scoped_ptr.h', 'scoped_temp_dir.cc', 'scoped_temp_dir.h', - 'scoped_variant_win.cc', - 'scoped_variant_win.h', 'scoped_vector.h', 'sha1.h', 'sha1_portable.cc', @@ -301,6 +295,15 @@ 'watchdog.h', 'weak_ptr.cc', 'weak_ptr.h', + 'win/scoped_bstr.cc', + 'win/scoped_bstr.h', + 'win/scoped_comptr.h', + 'win/scoped_gdi_object.h', + 'win/scoped_handle.h', + 'win/scoped_hdc.h', + 'win/scoped_hglobal.h', + 'win/scoped_variant.cc', + 'win/scoped_variant.h', 'win/windows_version.cc', 'win/windows_version.h', 'win_util.cc', @@ -363,6 +366,10 @@ 'sources/': [ ['exclude', '_openbsd\\.cc$'] ], }, ], + ['OS != "win"', { + 'sources/': [ ['exclude', '^win/'] ], + }, + ], [ 'OS == "win"', { 'include_dirs': [ '<(DEPTH)/third_party/wtl/include', @@ -377,10 +384,6 @@ 'string16.cc', 'trace_event.cc', ], - }, { # OS != "win" - 'sources/': [ - ['exclude', '/win/*'], - ], },], ], }], diff --git a/base/file_util_win.cc b/base/file_util_win.cc index 10a6b3b..213833b 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -16,13 +16,13 @@ #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/pe_image.h" -#include "base/scoped_comptr_win.h" -#include "base/scoped_handle.h" +#include "base/win/scoped_handle.h" #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/time.h" #include "base/utf_string_conversions.h" #include "base/win_util.h" +#include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" namespace file_util { @@ -328,7 +328,7 @@ bool GetFileCreationLocalTimeFromHandle(HANDLE file_handle, bool GetFileCreationLocalTime(const std::wstring& filename, LPSYSTEMTIME creation_time) { - ScopedHandle file_handle( + base::win::ScopedHandle file_handle( CreateFile(filename.c_str(), GENERIC_READ, kFileShareAll, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time); @@ -336,14 +336,14 @@ bool GetFileCreationLocalTime(const std::wstring& filename, bool ResolveShortcut(FilePath* path) { HRESULT result; - ScopedComPtr<IShellLink> i_shell_link; + base::win::ScopedComPtr<IShellLink> i_shell_link; bool is_resolved = false; // Get pointer to the IShellLink interface result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER); if (SUCCEEDED(result)) { - ScopedComPtr<IPersistFile> persist; + base::win::ScopedComPtr<IPersistFile> persist; // Query IShellLink for the IPersistFile interface result = persist.QueryFrom(i_shell_link); if (SUCCEEDED(result)) { @@ -374,8 +374,8 @@ bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination, DCHECK(lstrlen(arguments) < MAX_PATH); DCHECK(lstrlen(description) < MAX_PATH); - ScopedComPtr<IShellLink> i_shell_link; - ScopedComPtr<IPersistFile> i_persist_file; + base::win::ScopedComPtr<IShellLink> i_shell_link; + base::win::ScopedComPtr<IPersistFile> i_persist_file; // Get pointer to the IShellLink interface HRESULT result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, @@ -404,7 +404,7 @@ bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination, return false; if (app_id && (base::win::GetVersion() >= base::win::VERSION_WIN7)) { - ScopedComPtr<IPropertyStore> property_store; + base::win::ScopedComPtr<IPropertyStore> property_store; if (FAILED(property_store.QueryFrom(i_shell_link))) return false; @@ -426,12 +426,12 @@ bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination, DCHECK(lstrlen(description) < MAX_PATH); // Get pointer to the IPersistFile interface and load existing link - ScopedComPtr<IShellLink> i_shell_link; + base::win::ScopedComPtr<IShellLink> i_shell_link; if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER))) return false; - ScopedComPtr<IPersistFile> i_persist_file; + base::win::ScopedComPtr<IPersistFile> i_persist_file; if (FAILED(i_persist_file.QueryFrom(i_shell_link))) return false; @@ -454,7 +454,7 @@ bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination, return false; if (app_id && base::win::GetVersion() >= base::win::VERSION_WIN7) { - ScopedComPtr<IPropertyStore> property_store; + base::win::ScopedComPtr<IPropertyStore> property_store; if (FAILED(property_store.QueryFrom(i_shell_link))) return false; @@ -672,13 +672,13 @@ FILE* OpenFile(const std::string& filename, const char* mode) { } int ReadFile(const FilePath& filename, char* data, int size) { - ScopedHandle file(CreateFile(filename.value().c_str(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_SEQUENTIAL_SCAN, - NULL)); + base::win::ScopedHandle file(CreateFile(filename.value().c_str(), + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + NULL)); if (!file) return -1; @@ -690,13 +690,13 @@ int ReadFile(const FilePath& filename, char* data, int size) { } int WriteFile(const FilePath& filename, const char* data, int size) { - ScopedHandle file(CreateFile(filename.value().c_str(), - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - 0, - NULL)); + base::win::ScopedHandle file(CreateFile(filename.value().c_str(), + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + 0, + NULL)); if (!file) { LOG(WARNING) << "CreateFile failed for path " << filename.value() << " error code=" << GetLastError() << @@ -954,7 +954,7 @@ bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) { // code below to a call to GetFinalPathNameByHandle(). The method this // function uses is explained in the following msdn article: // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx - ScopedHandle file_handle( + base::win::ScopedHandle file_handle( ::CreateFile(path.value().c_str(), GENERIC_READ, kFileShareAll, @@ -968,7 +968,7 @@ bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) { // Create a file mapping object. Can't easily use MemoryMappedFile, because // we only map the first byte, and need direct access to the handle. You can // not map an empty file, this call fails in that case. - ScopedHandle file_map_handle( + base::win::ScopedHandle file_map_handle( ::CreateFileMapping(file_handle.Get(), NULL, PAGE_READONLY, @@ -1008,7 +1008,7 @@ bool PreReadImage(const wchar_t* file_path, size_t size_to_read, // Vista+ branch. On these OSes, the forced reads through the DLL actually // slows warm starts. The solution is to sequentially read file contents // with an optional cap on total amount to read. - ScopedHandle file( + base::win::ScopedHandle file( CreateFile(file_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, diff --git a/base/process_util_win.cc b/base/process_util_win.cc index 7a835d7..92077b1 100644 --- a/base/process_util_win.cc +++ b/base/process_util_win.cc @@ -16,8 +16,8 @@ #include "base/debug_util.h" #include "base/logging.h" #include "base/metrics/histogram.h" -#include "base/scoped_handle_win.h" #include "base/scoped_ptr.h" +#include "base/win/scoped_handle.h" #include "base/win/windows_version.h" // userenv.dll is required for CreateEnvironmentBlock(). @@ -163,7 +163,7 @@ bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level) { &process_token)) return false; - ScopedHandle scoped_process_token(process_token); + base::win::ScopedHandle scoped_process_token(process_token); DWORD token_info_length = 0; if (GetTokenInformation(process_token, TokenIntegrityLevel, NULL, 0, @@ -326,8 +326,8 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) { } // Ensure we don't leak the handles. - ScopedHandle scoped_out_read(out_read); - ScopedHandle scoped_out_write(out_write); + base::win::ScopedHandle scoped_out_read(out_read); + base::win::ScopedHandle scoped_out_write(out_write); // Ensure the read handle to the pipe for STDOUT is not inherited. if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) { diff --git a/base/scoped_bstr_win.h b/base/scoped_bstr_win.h index 42a9c218..98dbca4 100644 --- a/base/scoped_bstr_win.h +++ b/base/scoped_bstr_win.h @@ -1,142 +1,9 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_SCOPED_BSTR_WIN_H_ -#define BASE_SCOPED_BSTR_WIN_H_ -#pragma once +// TODO(brettw) remove this file when all callers are converted to using the +// new location/namespace +#include "base/win/scoped_bstr.h" -#include <windows.h> -#include <oleauto.h> - -#include "base/logging.h" - -// Manages a BSTR string pointer. -// The class interface is based on scoped_ptr. -class ScopedBstr { - public: - ScopedBstr() : bstr_(NULL) { - } - - // Constructor to create a new BSTR. - // NOTE: Do not pass a BSTR to this constructor expecting ownership to - // be transferred - even though it compiles! ;-) - explicit ScopedBstr(const wchar_t* non_bstr); - ~ScopedBstr(); - - // Give ScopedBstr ownership over an already allocated BSTR or NULL. - // If you need to allocate a new BSTR instance, use |allocate| instead. - void Reset(BSTR bstr = NULL); - - // Releases ownership of the BSTR to the caller. - BSTR Release(); - - // Creates a new BSTR from a wide string. - // If you already have a BSTR and want to transfer ownership to the - // ScopedBstr instance, call |reset| instead. - // Returns a pointer to the new BSTR, or NULL if allocation failed. - BSTR Allocate(const wchar_t* wide_str); - - // Allocates a new BSTR with the specified number of bytes. - // Returns a pointer to the new BSTR, or NULL if allocation failed. - BSTR AllocateBytes(int bytes); - - // Sets the allocated length field of the already-allocated BSTR to be - // |bytes|. This is useful when the BSTR was preallocated with e.g. - // SysAllocStringLen or SysAllocStringByteLen (call |AllocateBytes|) and - // then not all the bytes are being used. - // Note that if you want to set the length to a specific number of characters, - // you need to multiply by sizeof(wchar_t). Oddly, there's no public API to - // set the length, so we do this ourselves by hand. - // - // NOTE: The actual allocated size of the BSTR MUST be >= bytes. - // That responsibility is with the caller. - void SetByteLen(uint32 bytes); - - // Swap values of two ScopedBstr's. - void Swap(ScopedBstr& bstr2); - - // Retrieves the pointer address. - // Used to receive BSTRs as out arguments (and take ownership). - // The function DCHECKs on the current value being NULL. - // Usage: GetBstr(bstr.Receive()); - BSTR* Receive(); - - // Returns number of chars in the BSTR. - uint32 Length() const; - - // Returns the number of bytes allocated for the BSTR. - uint32 ByteLength() const; - - operator BSTR() const { - return bstr_; - } - - protected: - BSTR bstr_; - - private: - // Forbid comparison of ScopedBstr types. You should never have the same - // BSTR owned by two different scoped_ptrs. - bool operator==(const ScopedBstr& bstr2) const; - bool operator!=(const ScopedBstr& bstr2) const; - DISALLOW_COPY_AND_ASSIGN(ScopedBstr); -}; - -// Template class to generate a BSTR from a static wide string -// without touching the heap. Use this class via the StackBstrVar and -// StackBstr macros. -template <uint32 string_bytes> -class StackBstrT { - public: - // Try to stay as const as we can in an attempt to avoid someone - // using the class incorrectly (e.g. by supplying a variable instead - // of a verbatim string. We also have an assert in the constructor - // as an extra runtime check since the const-ness only catches one case. - explicit StackBstrT(const wchar_t* const str) { - // The BSTR API uses UINT, but we prefer uint32. - // Make sure we'll know about it if these types don't match. - COMPILE_ASSERT(sizeof(uint32) == sizeof(UINT), UintToUint32); - COMPILE_ASSERT(sizeof(wchar_t) == sizeof(OLECHAR), WcharToOlechar); - - // You shouldn't pass string pointers to this constructor since - // there's no way for the compiler to calculate the length of the - // string (string_bytes will be equal to pointer size in those cases). - DCHECK(lstrlenW(str) == (string_bytes / sizeof(bstr_.str_[0])) - 1) << - "not expecting a string pointer"; - memcpy(bstr_.str_, str, string_bytes); - bstr_.len_ = string_bytes - sizeof(wchar_t); - } - - operator BSTR() { - return bstr_.str_; - } - - protected: - struct BstrInternal { - uint32 len_; - wchar_t str_[string_bytes / sizeof(wchar_t)]; - } bstr_; -}; - -// Use this macro to generate an inline BSTR from a wide string. -// This is about 6 times faster than using the SysAllocXxx functions to -// allocate a BSTR and helps with keeping heap fragmentation down. -// Example: -// DoBstrStuff(StackBstr(L"This is my BSTR")); -// Where DoBstrStuff is: -// HRESULT DoBstrStuff(BSTR bstr) { ... } -#define StackBstr(str) \ - static_cast<BSTR>(StackBstrT<sizeof(str)>(str)) - -// If you need a named BSTR variable that's based on a fixed string -// (e.g. if the BSTR is used inside a loop or more than one place), -// use StackBstrVar to declare a variable. -// Example: -// StackBstrVar(L"my_property", myprop); -// for (int i = 0; i < objects.length(); ++i) -// ProcessValue(objects[i].GetProp(myprop)); // GetProp accepts BSTR -#define StackBstrVar(str, var) \ - StackBstrT<sizeof(str)> var(str) - -#endif // BASE_SCOPED_BSTR_WIN_H_ +using base::win::ScopedBstr; diff --git a/base/scoped_comptr_win.h b/base/scoped_comptr_win.h index dd9b9fc..7f15885 100644 --- a/base/scoped_comptr_win.h +++ b/base/scoped_comptr_win.h @@ -1,159 +1,9 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_SCOPED_COMPTR_WIN_H_ -#define BASE_SCOPED_COMPTR_WIN_H_ -#pragma once +// TODO(brettw) remove this file when all callers are converted to using the +// new location/namespace +#include "base/win/scoped_comptr.h" -#include <unknwn.h> - -#include "base/logging.h" -#include "base/ref_counted.h" - -// Utility template to prevent users of ScopedComPtr from calling AddRef and/or -// Release() without going through the ScopedComPtr class. -template <class Interface> -class BlockIUnknownMethods : public Interface { - private: - STDMETHOD(QueryInterface)(REFIID iid, void** object) = 0; - STDMETHOD_(ULONG, AddRef)() = 0; - STDMETHOD_(ULONG, Release)() = 0; -}; - -// A fairly minimalistic smart class for COM interface pointers. -// Uses scoped_refptr for the basic smart pointer functionality -// and adds a few IUnknown specific services. -template <class Interface, const IID* interface_id = &__uuidof(Interface)> -class ScopedComPtr : public scoped_refptr<Interface> { - public: - typedef scoped_refptr<Interface> ParentClass; - - ScopedComPtr() { - } - - explicit ScopedComPtr(Interface* p) : ParentClass(p) { - } - - ScopedComPtr(const ScopedComPtr<Interface, interface_id>& p) - : ParentClass(p) { - } - - ~ScopedComPtr() { - // We don't want the smart pointer class to be bigger than the pointer - // it wraps. - COMPILE_ASSERT(sizeof(ScopedComPtr<Interface, interface_id>) == - sizeof(Interface*), ScopedComPtrSize); - } - - // Explicit Release() of the held object. Useful for reuse of the - // ScopedComPtr instance. - // Note that this function equates to IUnknown::Release and should not - // be confused with e.g. scoped_ptr::release(). - void Release() { - if (ptr_ != NULL) { - ptr_->Release(); - ptr_ = NULL; - } - } - - // Sets the internal pointer to NULL and returns the held object without - // releasing the reference. - Interface* Detach() { - Interface* p = ptr_; - ptr_ = NULL; - return p; - } - - // Accepts an interface pointer that has already been addref-ed. - void Attach(Interface* p) { - DCHECK(ptr_ == NULL); - ptr_ = p; - } - - // Retrieves the pointer address. - // Used to receive object pointers as out arguments (and take ownership). - // The function DCHECKs on the current value being NULL. - // Usage: Foo(p.Receive()); - Interface** Receive() { - DCHECK(ptr_ == NULL) << "Object leak. Pointer must be NULL"; - return &ptr_; - } - - template <class Query> - HRESULT QueryInterface(Query** p) { - DCHECK(p != NULL); - DCHECK(ptr_ != NULL); - // IUnknown already has a template version of QueryInterface - // so the iid parameter is implicit here. The only thing this - // function adds are the DCHECKs. - return ptr_->QueryInterface(p); - } - - // QI for times when the IID is not associated with the type. - HRESULT QueryInterface(const IID& iid, void** obj) { - DCHECK(obj != NULL); - DCHECK(ptr_ != NULL); - return ptr_->QueryInterface(iid, obj); - } - - // Queries |other| for the interface this object wraps and returns the - // error code from the other->QueryInterface operation. - HRESULT QueryFrom(IUnknown* object) { - DCHECK(object != NULL); - return object->QueryInterface(Receive()); - } - - // Convenience wrapper around CoCreateInstance - HRESULT CreateInstance(const CLSID& clsid, IUnknown* outer = NULL, - DWORD context = CLSCTX_ALL) { - DCHECK(ptr_ == NULL); - HRESULT hr = ::CoCreateInstance(clsid, outer, context, *interface_id, - reinterpret_cast<void**>(&ptr_)); - return hr; - } - - // Checks if the identity of |other| and this object is the same. - bool IsSameObject(IUnknown* other) { - if (!other && !ptr_) - return true; - - if (!other || !ptr_) - return false; - - ScopedComPtr<IUnknown> my_identity; - QueryInterface(my_identity.Receive()); - - ScopedComPtr<IUnknown> other_identity; - other->QueryInterface(other_identity.Receive()); - - return static_cast<IUnknown*>(my_identity) == - static_cast<IUnknown*>(other_identity); - } - - // Provides direct access to the interface. - // Here we use a well known trick to make sure we block access to - // IUknown methods so that something bad like this doesn't happen: - // ScopedComPtr<IUnknown> p(Foo()); - // p->Release(); - // ... later the destructor runs, which will Release() again. - // and to get the benefit of the DCHECKs we add to QueryInterface. - // There's still a way to call these methods if you absolutely must - // by statically casting the ScopedComPtr instance to the wrapped interface - // and then making the call... but generally that shouldn't be necessary. - BlockIUnknownMethods<Interface>* operator->() const { - DCHECK(ptr_ != NULL); - return reinterpret_cast<BlockIUnknownMethods<Interface>*>(ptr_); - } - - // Pull in operator=() from the parent class. - using scoped_refptr<Interface>::operator=; - - // static methods - - static const IID& iid() { - return *interface_id; - } -}; - -#endif // BASE_SCOPED_COMPTR_WIN_H_ +using base::win::ScopedComPtr; diff --git a/base/scoped_handle_win.h b/base/scoped_handle_win.h index 4011a18..a98114b 100644 --- a/base/scoped_handle_win.h +++ b/base/scoped_handle_win.h @@ -2,237 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_SCOPED_HANDLE_WIN_H_ -#define BASE_SCOPED_HANDLE_WIN_H_ -#pragma once - -#include <windows.h> - -#include "base/basictypes.h" -#include "base/logging.h" - -// Used so we always remember to close the handle. -// The class interface matches that of ScopedStdioHandle in addition to an -// IsValid() method since invalid handles on windows can be either NULL or -// INVALID_HANDLE_VALUE (-1). -// -// Example: -// ScopedHandle hfile(CreateFile(...)); -// if (!hfile.Get()) -// ...process error -// ReadFile(hfile.Get(), ...); -// -// To sqirrel the handle away somewhere else: -// secret_handle_ = hfile.Take(); -// -// To explicitly close the handle: -// hfile.Close(); -class ScopedHandle { - public: - ScopedHandle() : handle_(NULL) { - } - - explicit ScopedHandle(HANDLE h) : handle_(NULL) { - Set(h); - } - - ~ScopedHandle() { - Close(); - } - - // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL - // usage for errors. - bool IsValid() const { - return handle_ != NULL; - } - - void Set(HANDLE new_handle) { - Close(); - - // Windows is inconsistent about invalid handles, so we always use NULL - if (new_handle != INVALID_HANDLE_VALUE) - handle_ = new_handle; - } - - HANDLE Get() { - return handle_; - } - - operator HANDLE() { return handle_; } - - HANDLE Take() { - // transfers ownership away from this object - HANDLE h = handle_; - handle_ = NULL; - return h; - } - - void Close() { - if (handle_) { - if (!::CloseHandle(handle_)) { - NOTREACHED(); - } - handle_ = NULL; - } - } - - private: - HANDLE handle_; - DISALLOW_COPY_AND_ASSIGN(ScopedHandle); -}; - -// Like ScopedHandle, but for HANDLEs returned from FindFile(). -class ScopedFindFileHandle { - public: - explicit ScopedFindFileHandle(HANDLE handle) : handle_(handle) { - // Windows is inconsistent about invalid handles, so we always use NULL - if (handle_ == INVALID_HANDLE_VALUE) - handle_ = NULL; - } - - ~ScopedFindFileHandle() { - if (handle_) - FindClose(handle_); - } - - // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL - // usage for errors. - bool IsValid() const { return handle_ != NULL; } - - operator HANDLE() { return handle_; } - - private: - HANDLE handle_; - - DISALLOW_COPY_AND_ASSIGN(ScopedFindFileHandle); -}; - -// Like ScopedHandle but for HDC. Only use this on HDCs returned from -// CreateCompatibleDC. For an HDC returned by GetDC, use ReleaseDC instead. -class ScopedHDC { - public: - ScopedHDC() : hdc_(NULL) { } - explicit ScopedHDC(HDC h) : hdc_(h) { } - - ~ScopedHDC() { - Close(); - } - - HDC Get() { - return hdc_; - } - - void Set(HDC h) { - Close(); - hdc_ = h; - } - - operator HDC() { return hdc_; } - - private: - void Close() { -#ifdef NOGDI - assert(false); -#else - if (hdc_) - DeleteDC(hdc_); -#endif // NOGDI - } - - HDC hdc_; - DISALLOW_COPY_AND_ASSIGN(ScopedHDC); -}; - -// Like ScopedHandle but for GDI objects. -template<class T> -class ScopedGDIObject { - public: - ScopedGDIObject() : object_(NULL) {} - explicit ScopedGDIObject(T object) : object_(object) {} - - ~ScopedGDIObject() { - Close(); - } - - T Get() { - return object_; - } - - void Set(T object) { - if (object_ && object != object_) - Close(); - object_ = object; - } - - ScopedGDIObject& operator=(T object) { - Set(object); - return *this; - } - - T release() { - T object = object_; - object_ = NULL; - return object; - } - - operator T() { return object_; } - - private: - void Close() { - if (object_) - DeleteObject(object_); - } - - T object_; - DISALLOW_COPY_AND_ASSIGN(ScopedGDIObject); -}; - -// An explicit specialization for HICON because we have to call DestroyIcon() -// instead of DeleteObject() for HICON. -template<> -void ScopedGDIObject<HICON>::Close() { - if (object_) - DestroyIcon(object_); -} - -// Typedefs for some common use cases. -typedef ScopedGDIObject<HBITMAP> ScopedBitmap; -typedef ScopedGDIObject<HRGN> ScopedRegion; -typedef ScopedGDIObject<HFONT> ScopedHFONT; -typedef ScopedGDIObject<HICON> ScopedHICON; - -// Like ScopedHandle except for HGLOBAL. -template<class T> -class ScopedHGlobal { - public: - explicit ScopedHGlobal(HGLOBAL glob) : glob_(glob) { - data_ = static_cast<T*>(GlobalLock(glob_)); - } - ~ScopedHGlobal() { - GlobalUnlock(glob_); - } - - T* get() { return data_; } - - size_t Size() const { return GlobalSize(glob_); } - - T* operator->() const { - assert(data_ != 0); - return data_; - } - - T* release() { - T* data = data_; - data_ = NULL; - return data; - } - - private: - HGLOBAL glob_; - - T* data_; - - DISALLOW_COPY_AND_ASSIGN(ScopedHGlobal); -}; - -#endif // BASE_SCOPED_HANDLE_WIN_H_ +// TODO(brettw) remove this file when all callers are converted to using the +// new location/namespace +#include "base/win/scoped_handle.h" +#include "base/win/scoped_gdi_object.h" +#include "base/win/scoped_handle.h" +#include "base/win/scoped_hdc.h" +#include "base/win/scoped_hglobal.h" + +using base::win::ScopedBitmap; +using base::win::ScopedGDIObject; +using base::win::ScopedHandle; +using base::win::ScopedHDC; +using base::win::ScopedHFONT; +using base::win::ScopedHGlobal; +using base::win::ScopedHICON; +using base::win::ScopedRegion; diff --git a/base/scoped_variant_win.h b/base/scoped_variant_win.h index c712e50..3d6b650 100644 --- a/base/scoped_variant_win.h +++ b/base/scoped_variant_win.h @@ -2,160 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_SCOPED_VARIANT_WIN_H_ -#define BASE_SCOPED_VARIANT_WIN_H_ -#pragma once +// TODO(brettw) remove this file when all callers are converted to using the +// new location/namespace +#include "base/win/scoped_variant.h" -#include <windows.h> -#include <oleauto.h> - -#include "base/basictypes.h" -#include "build/build_config.h" - -// Scoped VARIANT class for automatically freeing a COM VARIANT at the -// end of a scope. Additionally provides a few functions to make the -// encapsulated VARIANT easier to use. -// Instead of inheriting from VARIANT, we take the containment approach -// in order to have more control over the usage of the variant and guard -// against memory leaks. -class ScopedVariant { - public: - // Declaration of a global variant variable that's always VT_EMPTY - static const VARIANT kEmptyVariant; - - // Default constructor. - ScopedVariant() { - // This is equivalent to what VariantInit does, but less code. - var_.vt = VT_EMPTY; - } - - // Constructor to create a new VT_BSTR VARIANT. - // NOTE: Do not pass a BSTR to this constructor expecting ownership to - // be transferred - explicit ScopedVariant(const wchar_t* str); - - // Creates a new VT_BSTR variant of a specified length. - explicit ScopedVariant(const wchar_t* str, UINT length); - - // Creates a new integral type variant and assigns the value to - // VARIANT.lVal (32 bit sized field). - explicit ScopedVariant(int value, VARTYPE vt = VT_I4); - - // Creates a new double-precision type variant. |vt| must be either VT_R8 - // or VT_DATE. - explicit ScopedVariant(double value, VARTYPE vt = VT_R8); - - // VT_DISPATCH - explicit ScopedVariant(IDispatch* dispatch); - - // VT_UNKNOWN - explicit ScopedVariant(IUnknown* unknown); - - // SAFEARRAY - explicit ScopedVariant(SAFEARRAY* safearray); - - // Copies the variant. - explicit ScopedVariant(const VARIANT& var); - - ~ScopedVariant(); - - inline VARTYPE type() const { - return var_.vt; - } - - // Give ScopedVariant ownership over an already allocated VARIANT. - void Reset(const VARIANT& var = kEmptyVariant); - - // Releases ownership of the VARIANT to the caller. - VARIANT Release(); - - // Swap two ScopedVariant's. - void Swap(ScopedVariant& var); - - // Returns a copy of the variant. - VARIANT Copy() const; - - // The return value is 0 if the variants are equal, 1 if this object is - // greater than |var|, -1 if it is smaller. - int Compare(const VARIANT& var, bool ignore_case = false) const; - - // Retrieves the pointer address. - // Used to receive a VARIANT as an out argument (and take ownership). - // The function DCHECKs on the current value being empty/null. - // Usage: GetVariant(var.receive()); - VARIANT* Receive(); - - void Set(const wchar_t* str); - - // Setters for simple types. - void Set(int8 i8); - void Set(uint8 ui8); - void Set(int16 i16); - void Set(uint16 ui16); - void Set(int32 i32); - void Set(uint32 ui32); - void Set(int64 i64); - void Set(uint64 ui64); - void Set(float r32); - void Set(double r64); - void Set(bool b); - - // Creates a copy of |var| and assigns as this instance's value. - // Note that this is different from the Reset() method that's used to - // free the current value and assume ownership. - void Set(const VARIANT& var); - - // COM object setters - void Set(IDispatch* disp); - void Set(IUnknown* unk); - - // SAFEARRAY support - void Set(SAFEARRAY* array); - - // Special setter for DATE since DATE is a double and we already have - // a setter for double. - void SetDate(DATE date); - - // Allows const access to the contained variant without DCHECKs etc. - // This support is necessary for the V_XYZ (e.g. V_BSTR) set of macros to - // work properly but still doesn't allow modifications since we want control - // over that. - const VARIANT* operator&() const { - return &var_; - } - - // Like other scoped classes (e.g scoped_refptr, ScopedComPtr, ScopedBstr) - // we support the assignment operator for the type we wrap. - ScopedVariant& operator=(const VARIANT& var); - - // A hack to pass a pointer to the variant where the accepting - // function treats the variant as an input-only, read-only value - // but the function prototype requires a non const variant pointer. - // There's no DCHECK or anything here. Callers must know what they're doing. - VARIANT* AsInput() const { - // The nature of this function is const, so we declare - // it as such and cast away the constness here. - return const_cast<VARIANT*>(&var_); - } - - // Allows the ScopedVariant instance to be passed to functions either by value - // or by const reference. - operator const VARIANT&() const { - return var_; - } - - // Used as a debug check to see if we're leaking anything. - static bool IsLeakableVarType(VARTYPE vt); - - protected: - VARIANT var_; - - private: - // Comparison operators for ScopedVariant are not supported at this point. - // Use the Compare method instead. - bool operator==(const ScopedVariant& var) const; - bool operator!=(const ScopedVariant& var) const; - DISALLOW_COPY_AND_ASSIGN(ScopedVariant); -}; - -#endif // BASE_SCOPED_VARIANT_WIN_H_ +using base::win::ScopedVariant; diff --git a/base/test/test_file_util_win.cc b/base/test/test_file_util_win.cc index c15efa2..8e5b37b 100644 --- a/base/test/test_file_util_win.cc +++ b/base/test/test_file_util_win.cc @@ -64,7 +64,7 @@ bool EvictFileFromSystemCache(const FilePath& file) { DWORD bytes_read, bytes_written; for (;;) { bytes_read = 0; - ReadFile(file_handle, buffer, kOneMB, &bytes_read, NULL); + ::ReadFile(file_handle, buffer, kOneMB, &bytes_read, NULL); if (bytes_read == 0) break; @@ -82,7 +82,7 @@ bool EvictFileFromSystemCache(const FilePath& file) { // aligned, but that shouldn't happen here. DCHECK((total_bytes % kOneMB) == 0); SetFilePointer(file_handle, total_bytes, NULL, FILE_BEGIN); - if (!WriteFile(file_handle, buffer, kOneMB, &bytes_written, NULL) || + if (!::WriteFile(file_handle, buffer, kOneMB, &bytes_written, NULL) || bytes_written != kOneMB) { BOOL freed = VirtualFree(buffer, 0, MEM_RELEASE); DCHECK(freed); diff --git a/base/scoped_bstr_win.cc b/base/win/scoped_bstr.cc index 673aca2..18ffe6a 100644 --- a/base/scoped_bstr_win.cc +++ b/base/win/scoped_bstr.cc @@ -1,13 +1,15 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_bstr_win.h" +#include "base/win/scoped_bstr.h" #include "base/logging.h" +namespace base { +namespace win { -ScopedBstr::ScopedBstr(const wchar_t* non_bstr) +ScopedBstr::ScopedBstr(const char16* non_bstr) : bstr_(SysAllocString(non_bstr)) { } @@ -41,26 +43,29 @@ BSTR* ScopedBstr::Receive() { return &bstr_; } -BSTR ScopedBstr::Allocate(const wchar_t* wide_str) { - Reset(SysAllocString(wide_str)); +BSTR ScopedBstr::Allocate(const char16* str) { + Reset(SysAllocString(str)); return bstr_; } -BSTR ScopedBstr::AllocateBytes(int bytes) { - Reset(SysAllocStringByteLen(NULL, bytes)); +BSTR ScopedBstr::AllocateBytes(size_t bytes) { + Reset(SysAllocStringByteLen(NULL, static_cast<UINT>(bytes))); return bstr_; } -void ScopedBstr::SetByteLen(uint32 bytes) { +void ScopedBstr::SetByteLen(size_t bytes) { DCHECK(bstr_ != NULL) << "attempting to modify a NULL bstr"; uint32* data = reinterpret_cast<uint32*>(bstr_); - data[-1] = bytes; + data[-1] = static_cast<uint32>(bytes); } -uint32 ScopedBstr::Length() const { +size_t ScopedBstr::Length() const { return SysStringLen(bstr_); } -uint32 ScopedBstr::ByteLength() const { +size_t ScopedBstr::ByteLength() const { return SysStringByteLen(bstr_); } + +} // namespace win +} // namespace base diff --git a/base/win/scoped_bstr.h b/base/win/scoped_bstr.h new file mode 100644 index 0000000..944562e --- /dev/null +++ b/base/win/scoped_bstr.h @@ -0,0 +1,97 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_BSTR_H_ +#define BASE_WIN_SCOPED_BSTR_H_ +#pragma once + +#include <windows.h> +#include <oleauto.h> + +#include "base/logging.h" +#include "base/string16.h" + +namespace base { +namespace win { + +// Manages a BSTR string pointer. +// The class interface is based on scoped_ptr. +class ScopedBstr { + public: + ScopedBstr() : bstr_(NULL) { + } + + // Constructor to create a new BSTR. + // + // NOTE: Do not pass a BSTR to this constructor expecting ownership to + // be transferred - even though it compiles! ;-) + explicit ScopedBstr(const char16* non_bstr); + ~ScopedBstr(); + + // Give ScopedBstr ownership over an already allocated BSTR or NULL. + // If you need to allocate a new BSTR instance, use |allocate| instead. + void Reset(BSTR bstr = NULL); + + // Releases ownership of the BSTR to the caller. + BSTR Release(); + + // Creates a new BSTR from a 16-bit C-style string. + // + // If you already have a BSTR and want to transfer ownership to the + // ScopedBstr instance, call |reset| instead. + // + // Returns a pointer to the new BSTR, or NULL if allocation failed. + BSTR Allocate(const char16* str); + + // Allocates a new BSTR with the specified number of bytes. + // Returns a pointer to the new BSTR, or NULL if allocation failed. + BSTR AllocateBytes(size_t bytes); + + // Sets the allocated length field of the already-allocated BSTR to be + // |bytes|. This is useful when the BSTR was preallocated with e.g. + // SysAllocStringLen or SysAllocStringByteLen (call |AllocateBytes|) and then + // not all the bytes are being used. + // + // Note that if you want to set the length to a specific number of + // characters, you need to multiply by sizeof(wchar_t). Oddly, there's no + // public API to set the length, so we do this ourselves by hand. + // + // NOTE: The actual allocated size of the BSTR MUST be >= bytes. That + // responsibility is with the caller. + void SetByteLen(size_t bytes); + + // Swap values of two ScopedBstr's. + void Swap(ScopedBstr& bstr2); + + // Retrieves the pointer address. + // Used to receive BSTRs as out arguments (and take ownership). + // The function DCHECKs on the current value being NULL. + // Usage: GetBstr(bstr.Receive()); + BSTR* Receive(); + + // Returns number of chars in the BSTR. + size_t Length() const; + + // Returns the number of bytes allocated for the BSTR. + size_t ByteLength() const; + + operator BSTR() const { + return bstr_; + } + + protected: + BSTR bstr_; + + private: + // Forbid comparison of ScopedBstr types. You should never have the same + // BSTR owned by two different scoped_ptrs. + bool operator==(const ScopedBstr& bstr2) const; + bool operator!=(const ScopedBstr& bstr2) const; + DISALLOW_COPY_AND_ASSIGN(ScopedBstr); +}; + +} // namespace win +} // namespace base + +#endif // BASE_SCOPED_BSTR_H_ diff --git a/base/scoped_bstr_win_unittest.cc b/base/win/scoped_bstr_unittest.cc index fbb327a..5f6f7df 100644 --- a/base/scoped_bstr_win_unittest.cc +++ b/base/win/scoped_bstr_unittest.cc @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_bstr_win.h" +#include "base/win/scoped_bstr.h" #include "testing/gtest/include/gtest/gtest.h" +namespace base { +namespace win { + namespace { static const wchar_t kTestString1[] = L"123"; @@ -70,24 +73,5 @@ TEST(ScopedBstrTest, ScopedBstr) { BasicBstrTests(); } -#define kSourceStr L"this is a string" -#define kSourceStrEmpty L"" - -TEST(StackBstrTest, StackBstr) { - ScopedBstr system_bstr(kSourceStr); - StackBstrVar(kSourceStr, stack_bstr); - EXPECT_EQ(VARCMP_EQ, - VarBstrCmp(system_bstr, stack_bstr, LOCALE_USER_DEFAULT, 0)); - - StackBstrVar(kSourceStrEmpty, empty); - UINT l1 = SysStringLen(stack_bstr); - UINT l2 = SysStringLen(StackBstr(kSourceStr)); - UINT l3 = SysStringLen(system_bstr); - EXPECT_EQ(l1, l2); - EXPECT_EQ(l2, l3); - EXPECT_EQ(0, SysStringLen(empty)); - - const wchar_t one_more_test[] = L"this is my const string"; - EXPECT_EQ(SysStringLen(StackBstr(one_more_test)), - lstrlen(one_more_test)); -} +} // namespace win +} // namespace base diff --git a/base/win/scoped_comptr.h b/base/win/scoped_comptr.h new file mode 100644 index 0000000..385c79f --- /dev/null +++ b/base/win/scoped_comptr.h @@ -0,0 +1,165 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_COMPTR_H_ +#define BASE_WIN_SCOPED_COMPTR_H_ +#pragma once + +#include <unknwn.h> + +#include "base/logging.h" +#include "base/ref_counted.h" + +namespace base { +namespace win { + +// A fairly minimalistic smart class for COM interface pointers. +// Uses scoped_refptr for the basic smart pointer functionality +// and adds a few IUnknown specific services. +template <class Interface, const IID* interface_id = &__uuidof(Interface)> +class ScopedComPtr : public scoped_refptr<Interface> { + public: + // Utility template to prevent users of ScopedComPtr from calling AddRef + // and/or Release() without going through the ScopedComPtr class. + template <class Interface> + class BlockIUnknownMethods : public Interface { + private: + STDMETHOD(QueryInterface)(REFIID iid, void** object) = 0; + STDMETHOD_(ULONG, AddRef)() = 0; + STDMETHOD_(ULONG, Release)() = 0; + }; + + typedef scoped_refptr<Interface> ParentClass; + + ScopedComPtr() { + } + + explicit ScopedComPtr(Interface* p) : ParentClass(p) { + } + + ScopedComPtr(const ScopedComPtr<Interface, interface_id>& p) + : ParentClass(p) { + } + + ~ScopedComPtr() { + // We don't want the smart pointer class to be bigger than the pointer + // it wraps. + COMPILE_ASSERT(sizeof(ScopedComPtr<Interface, interface_id>) == + sizeof(Interface*), ScopedComPtrSize); + } + + // Explicit Release() of the held object. Useful for reuse of the + // ScopedComPtr instance. + // Note that this function equates to IUnknown::Release and should not + // be confused with e.g. scoped_ptr::release(). + void Release() { + if (ptr_ != NULL) { + ptr_->Release(); + ptr_ = NULL; + } + } + + // Sets the internal pointer to NULL and returns the held object without + // releasing the reference. + Interface* Detach() { + Interface* p = ptr_; + ptr_ = NULL; + return p; + } + + // Accepts an interface pointer that has already been addref-ed. + void Attach(Interface* p) { + DCHECK(ptr_ == NULL); + ptr_ = p; + } + + // Retrieves the pointer address. + // Used to receive object pointers as out arguments (and take ownership). + // The function DCHECKs on the current value being NULL. + // Usage: Foo(p.Receive()); + Interface** Receive() { + DCHECK(ptr_ == NULL) << "Object leak. Pointer must be NULL"; + return &ptr_; + } + + template <class Query> + HRESULT QueryInterface(Query** p) { + DCHECK(p != NULL); + DCHECK(ptr_ != NULL); + // IUnknown already has a template version of QueryInterface + // so the iid parameter is implicit here. The only thing this + // function adds are the DCHECKs. + return ptr_->QueryInterface(p); + } + + // QI for times when the IID is not associated with the type. + HRESULT QueryInterface(const IID& iid, void** obj) { + DCHECK(obj != NULL); + DCHECK(ptr_ != NULL); + return ptr_->QueryInterface(iid, obj); + } + + // Queries |other| for the interface this object wraps and returns the + // error code from the other->QueryInterface operation. + HRESULT QueryFrom(IUnknown* object) { + DCHECK(object != NULL); + return object->QueryInterface(Receive()); + } + + // Convenience wrapper around CoCreateInstance + HRESULT CreateInstance(const CLSID& clsid, IUnknown* outer = NULL, + DWORD context = CLSCTX_ALL) { + DCHECK(ptr_ == NULL); + HRESULT hr = ::CoCreateInstance(clsid, outer, context, *interface_id, + reinterpret_cast<void**>(&ptr_)); + return hr; + } + + // Checks if the identity of |other| and this object is the same. + bool IsSameObject(IUnknown* other) { + if (!other && !ptr_) + return true; + + if (!other || !ptr_) + return false; + + ScopedComPtr<IUnknown> my_identity; + QueryInterface(my_identity.Receive()); + + ScopedComPtr<IUnknown> other_identity; + other->QueryInterface(other_identity.Receive()); + + return static_cast<IUnknown*>(my_identity) == + static_cast<IUnknown*>(other_identity); + } + + // Provides direct access to the interface. + // Here we use a well known trick to make sure we block access to + // IUknown methods so that something bad like this doesn't happen: + // ScopedComPtr<IUnknown> p(Foo()); + // p->Release(); + // ... later the destructor runs, which will Release() again. + // and to get the benefit of the DCHECKs we add to QueryInterface. + // There's still a way to call these methods if you absolutely must + // by statically casting the ScopedComPtr instance to the wrapped interface + // and then making the call... but generally that shouldn't be necessary. + BlockIUnknownMethods<Interface>* operator->() const { + DCHECK(ptr_ != NULL); + return reinterpret_cast<BlockIUnknownMethods<Interface>*>(ptr_); + } + + // Pull in operator=() from the parent class. + using scoped_refptr<Interface>::operator=; + + // static methods + + static const IID& iid() { + return *interface_id; + } +}; + +} // namespace win +} // namespace base + +#endif // BASE_WIN_SCOPED_COMPTR_H_ diff --git a/base/scoped_comptr_win_unittest.cc b/base/win/scoped_comptr_unittest.cc index 3d22c56..fcd0791 100644 --- a/base/scoped_comptr_win_unittest.cc +++ b/base/win/scoped_comptr_unittest.cc @@ -2,13 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_comptr_win.h" +#include "base/win/scoped_comptr.h" #include <shlobj.h> #include "base/scoped_ptr.h" #include "testing/gtest/include/gtest/gtest.h" +namespace base { +namespace win { + namespace { struct Dummy { @@ -105,3 +108,6 @@ TEST(ScopedComPtrTest, ScopedComPtrVector) { EXPECT_EQ(p->adds, 4); EXPECT_EQ(p->releases, 4); } + +} // namespace win +} // namespace base
\ No newline at end of file diff --git a/base/win/scoped_gdi_object.h b/base/win/scoped_gdi_object.h new file mode 100644 index 0000000..3ce2245 --- /dev/null +++ b/base/win/scoped_gdi_object.h @@ -0,0 +1,78 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_GDI_OBJECT_H_ +#define BASE_WIN_SCOPED_GDI_OBJECT_H_ +#pragma once + +#include <windows.h> + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace base { +namespace win { + +// Like ScopedHandle but for GDI objects. +template<class T> +class ScopedGDIObject { + public: + ScopedGDIObject() : object_(NULL) {} + explicit ScopedGDIObject(T object) : object_(object) {} + + ~ScopedGDIObject() { + Close(); + } + + T Get() { + return object_; + } + + void Set(T object) { + if (object_ && object != object_) + Close(); + object_ = object; + } + + ScopedGDIObject& operator=(T object) { + Set(object); + return *this; + } + + T release() { + T object = object_; + object_ = NULL; + return object; + } + + operator T() { return object_; } + + private: + void Close() { + if (object_) + DeleteObject(object_); + } + + T object_; + DISALLOW_COPY_AND_ASSIGN(ScopedGDIObject); +}; + +// An explicit specialization for HICON because we have to call DestroyIcon() +// instead of DeleteObject() for HICON. +template<> +void ScopedGDIObject<HICON>::Close() { + if (object_) + DestroyIcon(object_); +} + +// Typedefs for some common use cases. +typedef ScopedGDIObject<HBITMAP> ScopedBitmap; +typedef ScopedGDIObject<HRGN> ScopedRegion; +typedef ScopedGDIObject<HFONT> ScopedHFONT; +typedef ScopedGDIObject<HICON> ScopedHICON; + +} // namespace win +} // namespace base + +#endif // BASE_WIN_SCOPED_GDI_OBJECT_H_ diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h new file mode 100644 index 0000000..3bb0279 --- /dev/null +++ b/base/win/scoped_handle.h @@ -0,0 +1,90 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_HANDLE_H_ +#define BASE_WIN_SCOPED_HANDLE_H_ +#pragma once + +#include <windows.h> + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace base { +namespace win { + +// Used so we always remember to close the handle. +// The class interface matches that of ScopedStdioHandle in addition to an +// IsValid() method since invalid handles on windows can be either NULL or +// INVALID_HANDLE_VALUE (-1). +// +// Example: +// ScopedHandle hfile(CreateFile(...)); +// if (!hfile.Get()) +// ...process error +// ReadFile(hfile.Get(), ...); +// +// To sqirrel the handle away somewhere else: +// secret_handle_ = hfile.Take(); +// +// To explicitly close the handle: +// hfile.Close(); +class ScopedHandle { + public: + ScopedHandle() : handle_(NULL) { + } + + explicit ScopedHandle(HANDLE h) : handle_(NULL) { + Set(h); + } + + ~ScopedHandle() { + Close(); + } + + // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL + // usage for errors. + bool IsValid() const { + return handle_ != NULL; + } + + void Set(HANDLE new_handle) { + Close(); + + // Windows is inconsistent about invalid handles, so we always use NULL + if (new_handle != INVALID_HANDLE_VALUE) + handle_ = new_handle; + } + + HANDLE Get() { + return handle_; + } + + operator HANDLE() { return handle_; } + + HANDLE Take() { + // transfers ownership away from this object + HANDLE h = handle_; + handle_ = NULL; + return h; + } + + void Close() { + if (handle_) { + if (!::CloseHandle(handle_)) { + NOTREACHED(); + } + handle_ = NULL; + } + } + + private: + HANDLE handle_; + DISALLOW_COPY_AND_ASSIGN(ScopedHandle); +}; + +} // namespace win +} // namespace base + +#endif // BASE_SCOPED_HANDLE_WIN_H_ diff --git a/base/win/scoped_hdc.h b/base/win/scoped_hdc.h new file mode 100644 index 0000000..73d369a7 --- /dev/null +++ b/base/win/scoped_hdc.h @@ -0,0 +1,55 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_HDC_H_ +#define BASE_WIN_SCOPED_HDC_H_ +#pragma once + +#include <windows.h> + +#include "base/basictypes.h" + +namespace base { +namespace win { + +// Like ScopedHandle but for HDC. Only use this on HDCs returned from +// CreateCompatibleDC. For an HDC returned by GetDC, use ReleaseDC instead. +class ScopedHDC { + public: + ScopedHDC() : hdc_(NULL) { } + explicit ScopedHDC(HDC h) : hdc_(h) { } + + ~ScopedHDC() { + Close(); + } + + HDC Get() { + return hdc_; + } + + void Set(HDC h) { + Close(); + hdc_ = h; + } + + operator HDC() { return hdc_; } + + private: + void Close() { +#ifdef NOGDI + assert(false); +#else + if (hdc_) + DeleteDC(hdc_); +#endif // NOGDI + } + + HDC hdc_; + DISALLOW_COPY_AND_ASSIGN(ScopedHDC); +}; + +} // namespace win +} // namespace base + +#endif // BASE_WIN_SCOPED_HDC_H_ diff --git a/base/win/scoped_hglobal.h b/base/win/scoped_hglobal.h new file mode 100644 index 0000000..23b36e4 --- /dev/null +++ b/base/win/scoped_hglobal.h @@ -0,0 +1,53 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_HGLOBAL_H_ +#define BASE_WIN_SCOPED_HGLOBAL_H_ +#pragma once + +#include <windows.h> + +#include "base/basictypes.h" + +namespace base { +namespace win { + +// Like ScopedHandle except for HGLOBAL. +template<class T> +class ScopedHGlobal { + public: + explicit ScopedHGlobal(HGLOBAL glob) : glob_(glob) { + data_ = static_cast<T*>(GlobalLock(glob_)); + } + ~ScopedHGlobal() { + GlobalUnlock(glob_); + } + + T* get() { return data_; } + + size_t Size() const { return GlobalSize(glob_); } + + T* operator->() const { + assert(data_ != 0); + return data_; + } + + T* release() { + T* data = data_; + data_ = NULL; + return data; + } + + private: + HGLOBAL glob_; + + T* data_; + + DISALLOW_COPY_AND_ASSIGN(ScopedHGlobal); +}; + +} // namespace win +} // namespace base + +#endif // BASE_WIN_SCOPED_HGLOBAL_H_ diff --git a/base/scoped_variant_win.cc b/base/win/scoped_variant.cc index dd4bceb..278e976 100644 --- a/base/scoped_variant_win.cc +++ b/base/win/scoped_variant.cc @@ -1,10 +1,13 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/scoped_variant_win.h" #include "base/logging.h" +namespace base { +namespace win { + // Global, const instance of an empty variant. const VARIANT ScopedVariant::kEmptyVariant = { VT_EMPTY }; @@ -268,3 +271,6 @@ bool ScopedVariant::IsLeakableVarType(VARTYPE vt) { return leakable; } + +} // namespace win +} // namespace base diff --git a/base/win/scoped_variant.h b/base/win/scoped_variant.h new file mode 100644 index 0000000..6c4d23f --- /dev/null +++ b/base/win/scoped_variant.h @@ -0,0 +1,166 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_VARIANT_H_ +#define BASE_WIN_SCOPED_VARIANT_H_ +#pragma once + +#include <windows.h> +#include <oleauto.h> + +#include "base/basictypes.h" + +namespace base { +namespace win { + +// Scoped VARIANT class for automatically freeing a COM VARIANT at the +// end of a scope. Additionally provides a few functions to make the +// encapsulated VARIANT easier to use. +// Instead of inheriting from VARIANT, we take the containment approach +// in order to have more control over the usage of the variant and guard +// against memory leaks. +class ScopedVariant { + public: + // Declaration of a global variant variable that's always VT_EMPTY + static const VARIANT kEmptyVariant; + + // Default constructor. + ScopedVariant() { + // This is equivalent to what VariantInit does, but less code. + var_.vt = VT_EMPTY; + } + + // Constructor to create a new VT_BSTR VARIANT. + // NOTE: Do not pass a BSTR to this constructor expecting ownership to + // be transferred + explicit ScopedVariant(const wchar_t* str); + + // Creates a new VT_BSTR variant of a specified length. + explicit ScopedVariant(const wchar_t* str, UINT length); + + // Creates a new integral type variant and assigns the value to + // VARIANT.lVal (32 bit sized field). + explicit ScopedVariant(int value, VARTYPE vt = VT_I4); + + // Creates a new double-precision type variant. |vt| must be either VT_R8 + // or VT_DATE. + explicit ScopedVariant(double value, VARTYPE vt = VT_R8); + + // VT_DISPATCH + explicit ScopedVariant(IDispatch* dispatch); + + // VT_UNKNOWN + explicit ScopedVariant(IUnknown* unknown); + + // SAFEARRAY + explicit ScopedVariant(SAFEARRAY* safearray); + + // Copies the variant. + explicit ScopedVariant(const VARIANT& var); + + ~ScopedVariant(); + + inline VARTYPE type() const { + return var_.vt; + } + + // Give ScopedVariant ownership over an already allocated VARIANT. + void Reset(const VARIANT& var = kEmptyVariant); + + // Releases ownership of the VARIANT to the caller. + VARIANT Release(); + + // Swap two ScopedVariant's. + void Swap(ScopedVariant& var); + + // Returns a copy of the variant. + VARIANT Copy() const; + + // The return value is 0 if the variants are equal, 1 if this object is + // greater than |var|, -1 if it is smaller. + int Compare(const VARIANT& var, bool ignore_case = false) const; + + // Retrieves the pointer address. + // Used to receive a VARIANT as an out argument (and take ownership). + // The function DCHECKs on the current value being empty/null. + // Usage: GetVariant(var.receive()); + VARIANT* Receive(); + + void Set(const wchar_t* str); + + // Setters for simple types. + void Set(int8 i8); + void Set(uint8 ui8); + void Set(int16 i16); + void Set(uint16 ui16); + void Set(int32 i32); + void Set(uint32 ui32); + void Set(int64 i64); + void Set(uint64 ui64); + void Set(float r32); + void Set(double r64); + void Set(bool b); + + // Creates a copy of |var| and assigns as this instance's value. + // Note that this is different from the Reset() method that's used to + // free the current value and assume ownership. + void Set(const VARIANT& var); + + // COM object setters + void Set(IDispatch* disp); + void Set(IUnknown* unk); + + // SAFEARRAY support + void Set(SAFEARRAY* array); + + // Special setter for DATE since DATE is a double and we already have + // a setter for double. + void SetDate(DATE date); + + // Allows const access to the contained variant without DCHECKs etc. + // This support is necessary for the V_XYZ (e.g. V_BSTR) set of macros to + // work properly but still doesn't allow modifications since we want control + // over that. + const VARIANT* operator&() const { + return &var_; + } + + // Like other scoped classes (e.g scoped_refptr, ScopedComPtr, ScopedBstr) + // we support the assignment operator for the type we wrap. + ScopedVariant& operator=(const VARIANT& var); + + // A hack to pass a pointer to the variant where the accepting + // function treats the variant as an input-only, read-only value + // but the function prototype requires a non const variant pointer. + // There's no DCHECK or anything here. Callers must know what they're doing. + VARIANT* AsInput() const { + // The nature of this function is const, so we declare + // it as such and cast away the constness here. + return const_cast<VARIANT*>(&var_); + } + + // Allows the ScopedVariant instance to be passed to functions either by value + // or by const reference. + operator const VARIANT&() const { + return var_; + } + + // Used as a debug check to see if we're leaking anything. + static bool IsLeakableVarType(VARTYPE vt); + + protected: + VARIANT var_; + + private: + // Comparison operators for ScopedVariant are not supported at this point. + // Use the Compare method instead. + bool operator==(const ScopedVariant& var) const; + bool operator!=(const ScopedVariant& var) const; + DISALLOW_COPY_AND_ASSIGN(ScopedVariant); +}; + +} // namespace win +} // namesoace base + +#endif // BASE_WIN_SCOPED_VARIANT_H_ diff --git a/base/scoped_variant_win_unittest.cc b/base/win/scoped_variant_unittest.cc index 8588e17..2cd5be1 100644 --- a/base/scoped_variant_win_unittest.cc +++ b/base/win/scoped_variant_unittest.cc @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_variant_win.h" +#include "base/win/scoped_variant.h" #include "testing/gtest/include/gtest/gtest.h" +namespace base { +namespace win { + namespace { static const wchar_t kTestString1[] = L"Used to create BSTRs"; @@ -255,3 +258,6 @@ TEST(ScopedVariantTest, ScopedVariant) { EXPECT_EQ(sa, V_ARRAY(&var)); // The array is destroyed in the destructor of var. } + +} // namespace win +} // namespace base diff --git a/chrome/installer/util/wmi.cc b/chrome/installer/util/wmi.cc index 957ec99..fca2076 100644 --- a/chrome/installer/util/wmi.cc +++ b/chrome/installer/util/wmi.cc @@ -7,8 +7,8 @@ #include <windows.h> #include "base/basictypes.h" -#include "base/scoped_bstr_win.h" -#include "base/scoped_comptr_win.h" +#include "base/win/scoped_bstr.h" +#include "base/win/scoped_comptr.h" #pragma comment(lib, "wbemuuid.lib") @@ -37,15 +37,16 @@ class VariantHelper : public VARIANT { bool WMI::CreateLocalConnection(bool set_blanket, IWbemServices** wmi_services) { - ScopedComPtr<IWbemLocator> wmi_locator; + base::win::ScopedComPtr<IWbemLocator> wmi_locator; HRESULT hr = wmi_locator.CreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER); if (FAILED(hr)) return false; - ScopedComPtr<IWbemServices> wmi_services_r; - hr = wmi_locator->ConnectServer(StackBstr(L"ROOT\\CIMV2"), NULL, NULL, 0, - NULL, 0, 0, wmi_services_r.Receive()); + base::win::ScopedComPtr<IWbemServices> wmi_services_r; + hr = wmi_locator->ConnectServer(base::win::ScopedBstr(L"ROOT\\CIMV2"), + NULL, NULL, 0, NULL, 0, 0, + wmi_services_r.Receive()); if (FAILED(hr)) return false; @@ -72,16 +73,16 @@ bool WMI::CreateClassMethodObject(IWbemServices* wmi_services, IWbemClassObject** class_instance) { // We attempt to instantiate a COM object that represents a WMI object plus // a method rolled into one entity. - ScopedBstr b_class_name(class_name.c_str()); - ScopedBstr b_method_name(method_name.c_str()); - ScopedComPtr<IWbemClassObject> class_object; + base::win::ScopedBstr b_class_name(class_name.c_str()); + base::win::ScopedBstr b_method_name(method_name.c_str()); + base::win::ScopedComPtr<IWbemClassObject> class_object; HRESULT hr; hr = wmi_services->GetObject(b_class_name, 0, NULL, class_object.Receive(), NULL); if (FAILED(hr)) return false; - ScopedComPtr<IWbemClassObject> params_def; + base::win::ScopedComPtr<IWbemClassObject> params_def; hr = class_object->GetMethod(b_method_name, 0, params_def.Receive(), NULL); if (FAILED(hr)) return false; @@ -108,13 +109,13 @@ bool SetParameter(IWbemClassObject* class_method, // http://msdn2.microsoft.com/en-us/library/aa389388(VS.85).aspx bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) { - ScopedComPtr<IWbemServices> wmi_local; + base::win::ScopedComPtr<IWbemServices> wmi_local; if (!WMI::CreateLocalConnection(true, wmi_local.Receive())) return false; const wchar_t class_name[] = L"Win32_Process"; const wchar_t method_name[] = L"Create"; - ScopedComPtr<IWbemClassObject> process_create; + base::win::ScopedComPtr<IWbemClassObject> process_create; if (!WMI::CreateClassMethodObject(wmi_local, class_name, method_name, process_create.Receive())) return false; @@ -125,11 +126,11 @@ bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) { if (!SetParameter(process_create, L"CommandLine", &b_command_line)) return false; - ScopedComPtr<IWbemClassObject> out_params; - HRESULT hr = wmi_local->ExecMethod(StackBstr(class_name), - StackBstr(method_name), 0, NULL, - process_create, out_params.Receive(), - NULL); + base::win::ScopedComPtr<IWbemClassObject> out_params; + HRESULT hr = wmi_local->ExecMethod(base::win::ScopedBstr(class_name), + base::win::ScopedBstr(method_name), + 0, NULL, process_create, + out_params.Receive(), NULL); if (FAILED(hr)) return false; diff --git a/chrome_frame/chrome_frame_activex.cc b/chrome_frame/chrome_frame_activex.cc index f137aad..13ad0fa 100644 --- a/chrome_frame/chrome_frame_activex.cc +++ b/chrome_frame/chrome_frame_activex.cc @@ -15,13 +15,14 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/process_util.h" -#include "base/scoped_bstr_win.h" #include "base/singleton.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "base/trace_event.h" #include "base/utf_string_conversions.h" +#include "base/win/scoped_bstr.h" +#include "base/win/scoped_variant.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/automation/tab_proxy.h" @@ -214,7 +215,7 @@ void ChromeFrameActivex::OnMessageFromChromeFrame(int tab_handle, ScopedComPtr<IDispatch> message_event; if (SUCCEEDED(CreateDomEvent("message", message, origin, message_event.Receive()))) { - ScopedBstr target_bstr(UTF8ToWide(target).c_str()); + base::win::ScopedBstr target_bstr(UTF8ToWide(target).c_str()); Fire_onprivatemessage(message_event, target_bstr); FireEvent(onprivatemessage_, message_event, target_bstr); @@ -239,7 +240,7 @@ void ChromeFrameActivex::OnMessageFromChromeFrame(int tab_handle, FireEvent(onmessage_, message_event); - ScopedVariant event_var; + base::win::ScopedVariant event_var; event_var.Set(static_cast<IDispatch*>(message_event)); InvokeScriptFunction(onmessage_handler_, event_var.AsInput()); } @@ -258,7 +259,7 @@ void ChromeFrameActivex::OnExtensionInstalled( const FilePath& path, void* user_data, AutomationMsg_ExtensionResponseValues response) { - ScopedBstr path_str(path.value().c_str()); + base::win::ScopedBstr path_str(path.value().c_str()); Fire_onextensionready(path_str, response); } @@ -313,10 +314,10 @@ STDMETHODIMP ChromeFrameActivex::Load(IPropertyBag* bag, IErrorLog* error_log) { (L"onreadystatechanged"), }; - ScopedComPtr<IHTMLObjectElement> obj_element; + base::win::ScopedComPtr<IHTMLObjectElement> obj_element; GetObjectElement(obj_element.Receive()); - ScopedBstr object_id; + base::win::ScopedBstr object_id; GetObjectScriptId(obj_element, object_id.Receive()); ScopedComPtr<IHTMLElement2> element; @@ -324,8 +325,8 @@ STDMETHODIMP ChromeFrameActivex::Load(IPropertyBag* bag, IErrorLog* error_log) { HRESULT hr = S_OK; for (int i = 0; SUCCEEDED(hr) && i < arraysize(event_props); ++i) { - ScopedBstr prop(event_props[i]); - ScopedVariant value; + base::win::ScopedBstr prop(event_props[i]); + base::win::ScopedVariant value; if (SUCCEEDED(bag->Read(prop, value.Receive(), error_log))) { if (value.type() != VT_BSTR || FAILED(hr = CreateScriptBlockForEvent(element, object_id, @@ -343,16 +344,17 @@ STDMETHODIMP ChromeFrameActivex::Load(IPropertyBag* bag, IErrorLog* error_log) { } } - ScopedVariant src; - if (SUCCEEDED(bag->Read(StackBstr(L"src"), src.Receive(), error_log))) { + base::win::ScopedVariant src; + if (SUCCEEDED(bag->Read(base::win::ScopedBstr(L"src"), src.Receive(), + error_log))) { if (src.type() == VT_BSTR) { hr = put_src(V_BSTR(&src)); DCHECK(hr != E_UNEXPECTED); } } - ScopedVariant use_chrome_network; - if (SUCCEEDED(bag->Read(StackBstr(L"useChromeNetwork"), + base::win::ScopedVariant use_chrome_network; + if (SUCCEEDED(bag->Read(base::win::ScopedBstr(L"useChromeNetwork"), use_chrome_network.Receive(), error_log))) { VariantChangeType(use_chrome_network.AsInput(), use_chrome_network.AsInput(), @@ -431,7 +433,7 @@ HRESULT ChromeFrameActivex::IOleObject_SetClientSite( std::wstring profile_name(GetHostProcessName(false)); if (is_privileged_) { // Does the host want to provide extra arguments? - ScopedBstr extra_arguments_arg; + base::win::ScopedBstr extra_arguments_arg; service_hr = service->GetChromeExtraArguments( extra_arguments_arg.Receive()); if (S_OK == service_hr && extra_arguments_arg) @@ -451,7 +453,7 @@ HRESULT ChromeFrameActivex::IOleObject_SetClientSite( base::SplitString(automated_functions, ',', &functions_enabled_); } - ScopedBstr profile_name_arg; + base::win::ScopedBstr profile_name_arg; service_hr = service->GetChromeProfileName(profile_name_arg.Receive()); if (S_OK == service_hr && profile_name_arg) profile_name.assign(profile_name_arg, profile_name_arg.Length()); @@ -661,7 +663,7 @@ HRESULT ChromeFrameActivex::registerBhoIfNeeded() { return hr; } - web_browser2->PutProperty(ScopedBstr(bho_class_id_as_string), + web_browser2->PutProperty(base::win::ScopedBstr(bho_class_id_as_string), ScopedVariant(bho)); return S_OK; } diff --git a/net/disk_cache/cache_util_win.cc b/net/disk_cache/cache_util_win.cc index 3e1d673..cbe6b87 100644 --- a/net/disk_cache/cache_util_win.cc +++ b/net/disk_cache/cache_util_win.cc @@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/message_loop.h" -#include "base/scoped_handle.h" #include "base/file_util.h" namespace { @@ -19,8 +18,8 @@ void DeleteFiles(const wchar_t* path, const wchar_t* search_name) { file_util::AppendToPath(&name, search_name); WIN32_FIND_DATA data; - ScopedFindFileHandle handle(FindFirstFile(name.c_str(), &data)); - if (!handle.IsValid()) + HANDLE handle = FindFirstFile(name.c_str(), &data); + if (handle == INVALID_HANDLE_VALUE) return; std::wstring adjusted_path(path); @@ -33,6 +32,8 @@ void DeleteFiles(const wchar_t* path, const wchar_t* search_name) { current += data.cFileName; DeleteFile(current.c_str()); } while (FindNextFile(handle, &data)); + + FindClose(handle); } } // namespace |