(PUP-2881) Move COM FFI to file windows/com.rb

 - This is the start of a new era, FFI / COM integration.  Run, hide!
 - Start by sliding over FFI function definitions for Win32 COM APIs
   and HRESULT macros.
 - Use a better ComInitialize function that will properly call
   CoUninitialize on application exit.
(PUP-2881) Add Windows COM code from Unknownr

 - Unknownr project at https://github.com/rpeev/Unknownr defines FFI
   bindings around COM interfaces / classes
 - Unknownr is MIT licensed, and only relevant bits have been brought
   into project
 - FFI based wrappers for COM interfaces in the form of 3 new modules
   Interface - for defining COM interfaces by GUID / FFI types
   Factory - for creating a COM object instance by CLSID GUID and
     returning a specified interface type
   Instance - for use when calling QueryInterface on an existing COM
     object to return a class of another type
 - FFI definition for GUID
 - NOTE: Had to add an FFI layout to the Factory class.  The original
   Unknownr code was using a different, older FFI version where this
   might have worked.  In newer code, inheriting from the Interface
   is not enough to pick up the layout in the FFI::Struct that is the
   Interface.
(PUP-2881) Use Windows::Error for COM call fails

 - Update error message / class type to be more consistent with other
   Puppet code
(PUP-2881) Fix Unknownr UseInstance helper

 - Existing code passes an additional unecessary GUID in the call to
   the COM function.
 - Add extra safety check to ensure FFI pointer is not pointing to a
   NULL block of memory
(PUP-2881) Refactor ITaskScheduler for FFI / COM

 - Using the magical COM binding / meta-programming techniques of
   Unknownr, define the ITaskScheduler COM interface as a special
   FFI::Struct derived type.  It uses our local mapping to make calls
   directly to the relevant methods on the interface pointer.
 - Greatly simplify the creation of the ITaskScheduler COM object
 - Properly allocate / cleanup memory with FFI pointer block form
 - No need to manually check HRESULT failure, as the COM wrappers
   will automatically throw exceptions when FAILED HRESULTs encountered
 - Define CLSID_CTask and IID_ITask in terms of the new GUID type
   instead of antiquated Ruby packing techniques
 - Change new_work_item to return the current task (otherwise, it would
   return an invalid FFI::Pointer)
 - With no more calls to CoCreateInstance, mark it as a private member
   of Puppet::Util::Windows::COM
(PUP-2881) Refactor IEnumWorkItems for FFI / COM

 - Create IEnumWorkItems interface definition, and rewrite code
   using this interface to safely clean-up memory and call Release on
   the COM interface pointer
 - Rework task name string reading to use FFI pointers safely that
   are the correct width on all platforms
 - Add new FFI::Pointer helper read_com_memory_pointer that will
   automatically call CoTaskMemFree on the pointer
 - To implement this helper, CoTaskMemFree has been copied into the
   api_types code
 - Add new alias to read_win32_long from an FFI::Pointer
(PUP-2881) Setup Taskscheduler HRESULT constants
(PUP-2881) Refactor ITask for FFI / COM

 - Using the magical COM binding / meta-programming techniques of
   Unknownr, define the IScheduledWorkItem and ITask COM interfaces as
   special FFI::Struct derived types.  It uses our local mapping to make
   calls directly to the relevant methods on the interface pointer.
 - Greatly simplify calling ITask COM object functions
 - Properly allocate / cleanup memory with FFI pointer block form and
   properly cleanup COM allocated strings using the
   read_com_memory_pointer helper
 - No need to manually check HRESULT failure, as the COM wrappers
   will automatically throw exceptions when FAILED HRESULTs encountered
   In some instances, ITask methods should not bubble up known
   HRESULTs as exceptions since they are expected failures under some
   circumstances, such as account_information / set_account_information,
   exit_code, and most_recent_run_time
 - On a related note, add another acceptable failure HRESULT of
   -2147023564 for when the SID attached to a job cannot be resolved to
   a name.
 - Define IID_IPersistFile in terms of the new GUID type instead of
   antiquated Ruby packing techniques
(PUP-2881) Remove CoTaskMemFree in windows/com.rb

 - Taskscheduler code now uses only COM pointer helper methods that
   use blocks and free up memory, so this FFI definition is no longer
   required.
(PUP-2881) Refactor IPersistFile for FFI / COM

 - Using the magical COM binding / meta-programming techniques of
   Unknownr, define the IPersist and IPersistFile COM interfaces as
   special FFI::Struct derived types.  It uses our local mapping to make
   calls directly to the relevant methods on the interface pointer.
 - Add FFI typedef for LPCOLESTR
 - Simplify calling PersistFile method, and add error handling to
   the save method to ensure that IPersistFile COM interface pointer
   is cleaned up
(PUP-2881) Refactor ITaskTrigger for FFI / COM

 - Define ITaskTrigger COM interface and the relevant struct types using
   FFI
 - Update low-level memory copying and function call definitions to use
   COM wrappers
 - Properly allocate / cleanup memory with FFI pointer block form
 - No need to manually check HRESULT failure, as the COM wrappers
   will automatically throw exceptions when FAILED HRESULTs encountered
 - Refactored redundant code that tasks a Ruby hash and populates the
   ITaskTrigger object into the populate_trigger method - this is called
   by new_work_item, trigger= and add_trigger
 - Refactor COM struct to Ruby hash conversion code into
   populate_hash_from_trigger
 - In returned hash, use the COM enum constants like :TASK_XXX instead of
   the class constants TASK_XXX. Similarly redefined the
   Win32::TaskScheduler constants TASK_XXX to use symbols so as to match
   the FFI definition
 - Had to extend our TaskScheduler::COM with FFI::Library to gain
   enum definition abilities
 - Note that TRIGGER_TYPE_UNION is an FFI::Union rather than an
   FFI::Struct so that it's properly laid out in memory and so that the
   COM::TASK_TRIGGER struct size is correct at 48 bytes
(PUP-2881) Remove msvcrt/buffer from taskscheduler

 - Last appendage hanging on from windows-pr
(PUP-2881) Remove taskscheduler S_OK constant
(PUP-2881) Taskscheduler COM initialization

 - For unknown reasons, the prior win32-taskscheduler gem code was
   calling CoInitialize / CoUninitialize in the 'save' method. The calls
   in 'save' to CoUninitialize was not safe in that it wasn't
   guaranteed to be called when the application terminates.
 - COM only needs to be initialized once per thread.  Since Puppet is
   not multi-threaded / thread-safe, it's OK to assume that each new
   TaskScheduler instance lands on the same thread.  Therefore, use a
   class variable to track whether CoInitialize has been called
   appropriately or not.  Multiple calls to CoInitialize would
   technically be a no-op (as long as they're paired with equivalent
   calls to CoUninitalize), but rather than stack up a number of
   at_exit handlers, simply keep track of COM initialization in the
   class itself
   http://msdn.microsoft.com/en-us/library/windows/desktop/ms678543(v=vs.85).aspx
(PUP-2881) Remove taskscheduler VERSION

 - No longer relevant
(PUP-2881) Use COM interface pointer helper

 - Rather than using QueryInterface directly, use the QueryInstance
   helper to return a COM interface pointer in a block and call
   Release as soon as the block has completed.  Note that QueryInstance
   handles allocation of a temporary pointer to hold the COM interface
   pointer that must be dereferenced.
(PUP-2881) Refactor Task cleanup

 - In an unsuccessful 'save' situation do not reset the TaskScheduler
   instance and Task instance.  Instead, if an exception is thrown,
   do not perform cleanup.
 - In the new_work_item code, don't reset the current task until *after*
   the NewWorkItem COM method has succeeded.
 - In the activate code, if there is already a @pITask, Release it prior
   to creating / assigning a new one.
(PUP-2881) Don't Release TaskScheduler in save

 - It doesn't make a lot of sense to reset the TaskScheduler instance
   upon save, given the current Task has release called and is set to
   nil.  There are no methods called against @pITaskScheduler that
   have any bearing on 'the current task'.  Any methods that need
   a valid @pITask are already guarded.
(PUP-2881) Use COM UseInstance Helper for cleanup

 - The UseInstance helper makes a call against a COM interface pointer
   function, and expects to return a given COM instance type as passed
   in.  The function is expected to always have the last parameter be
   the pointer that accepts the new pointer that must be dereferenced
   to the new COM interface pointer.
 - Using this block form simplifies existing cleanup code, and makes it
   more reliable by always ensuring Release is called against the newly
   returned COM interface pointer when the block completes.