Uploaded image for project: 'Facter'
  1. Facter
  2. FACT-1082

COM initialization prior to ruby COM initialization


    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: FACT 3.0.0
    • Fix Version/s: FACT 3.0.2
    • Component/s: None
    • Labels:
    • Template:
    • Story Points:
    • Sprint:
      Client 2015-07-08
    • Release Notes:
      Bug Fix
    • Release Notes Summary:
      Using WIN32OLE from Ruby as part of a custom fact in command-line Facter results in an error. This is fixed.


      OLE COM initialized prior to Ruby causing issue with later COM calls.
      SQLSERVER Instances Fact
      sqlserver ole calls

      [4:01 PM] Ethan J. Brown: it looks like Facter initializes COM in the wmi class (inside Leatherman) at https://github.com/puppetlabs/leatherman/blob/master/windows/src/wmi.cc#L34
      [4:01 PM] Ethan J. Brown: CoInitializeEx(0, COINIT_MULTITHREADED)
      		Ruby initializes COM at https://github.com/ruby/ruby/blob/c19d37375074987b36413af6bf83df7262ce227d/ext/win32ole/win32ole.c#L...
      [4:02 PM] Ethan J. Brown: hr = OleInitialize(NULL);
      		so if you call Puppet -> Facter, everything is OK
      [4:02 PM] Michael Smith: oh single vs multithreaded?
      [4:02 PM] Ethan J. Brown: however if you call in the reverse to resolve a custom fact
      		then barf
      [4:03 PM] Ethan J. Brown: OleInitialize calls CoInitializeEx internally to initialize the COM library on the current apartment. Because OLE operations are not thread-safe, OleInitialize specifies the concurrency model as single-thread apartment.
      		Once the concurrency model for an apartment is set, it cannot be changed. A call to OleInitialize on an apartment that was previously initialized as multithreaded will fail and return RPC_E_CHANGED_MODE.
      [4:04 PM] Michael Smith: yeah, so we accept that it might've been initialized with single-threaded, but ruby errors out
      		so I guess we have to initialize apartmentthreaded? ugh
      		We could do so only when loaded in ruby...
      		Wait, I'm still not sure how that happens.
      [4:06 PM] Travis Fields: it is when cfacter is called prior to ruby, if puppet is called first the fact that is returned is correct with no errors
      [4:06 PM] Ethan J. Brown: the output from Travis is at https://gist.github.com/cyberious/52410266b650afd94b59
      [4:06 PM] Peter Huene: facter initializes COM then tries to resolve a custom fact that uses ruby's COM support
      		since ruby doesn't handle RPC_E_CHANGED_MODE it seems, boom
      [4:07 PM] Ethan J. Brown: correct
      [4:07 PM] Michael Smith: ok, so we just have to always use single-threaded.
      		Well, we don't multi-thread queries to COM yet, so shouldn't cause any issues to change.


          Issue Links



              • Assignee:
                travis Travis Fields
              • Votes:
                0 Vote for this issue
                3 Start watching this issue


                • Created:

                  Zendesk Support

                    Time Tracking

                    Original Estimate - Not Specified
                    Not Specified
                    Remaining Estimate - 0 minutes
                    Time Spent - 10 minutes