tags:

views:

10

answers:

1

I want to retrieve the version information of msi-package(s)

What's the better way?

First: Guessing a buffer that is large enough and recall if it doesn't fit (ERROR_MORE_DATA)
1 func call vs. 3 func calls and buffer can be bigger then needed

Second: Call the api function to get the buffer size and then recall it to get the string with a (perfect) matching buffer size
2 func calls every time with a perfect buffer size

It's about (1 or 3) function call(s) vs. 2 function calls every time.

Is there any best practice for this "problem"?

I hope to get a generalized answer (assume calling function is really time consuming and/or buffer size can be very different (10 bytes to 200 megabyte) for further code writing. :-)

pseudo code:

First:

StringBuffer = 10 // (byte) guessing returned string will fit in 10 bytes  

result = MsiGetProductInfoW(
  product,
  INSTALLPROPERTY_VERSIONSTRING,
  VersionString,
  StringBuffer
); //maybe it fits in 10

if result = ERROR_MORE_DATA then //doesnt fit in 10 so recall to get the correct buffer size
begin
  MsiGetProductInfoW(
    product,
    INSTALLPROPERTY_VERSIONSTRING,
    nil,
    StringBuffer
  );

  Inc(StringBuffer); // cause null-terminated string

  // recall it with matching
  MsiGetProductInfoW(
    product,
    INSTALLPROPERTY_VERSIONSTRING,
    VersionString,
    StringBuffer
  );
end;

Second:

StringBuffer = 0;

// get buffer size
MsiGetProductInfoW(
  product,
  INSTALLPROPERTY_VERSIONSTRING,
  nil,
  StringBuffer
);

Inc(StringBuffer); // cause null-terminated string

// use it with the correct buffersize
MsiGetProductInfoW(
  product,
  INSTALLPROPERTY_VERSIONSTRING,
  VersionString,
  StringBuffer
);

Thank you!

A: 

In your First option, you can skip the second call, because even on the failing first call, the needed size should be stored in StringBuffer.

This makes the choice (1 or 2) vs. (always 2). That should be clear enough. Further, it shouldn't be hard to come up with a reasonable-sized buffer, that will pass 90+% of the time.

James Curran