decompressing str in win32

After compressing a string using the CompressData function if WFS, I’m having problems decompressing a compressed file using the DecompressData function in WFS.

dim mm,mmm as MemoryBlock
mm = myCompressedString
mmm = DecompressData(mm)
dim s as string = mmm
s = DefineEncoding(s, Encodings.utf8)

but I get a nilobject exception; so I tried: mmm = DecompressData(mm,15000000), still the exception.

Can somebody show me how the DecompressData function should be called? Thanks.
BTW: using the undocumented GzipString of Xojo, things work all right; but I’d refrain using something that may be unsupported tomorrow.

Protected Function DecompressData(data as MemoryBlock, bufferSize as Integer = 10485760) As MemoryBlock
#if TargetWin32

Soft Declare Sub RtlDecompressBuffer Lib "ntdll" ( format as Integer, destBuffer as Ptr, _
destLength as Integer, sourceBuffer as Ptr, sourceLength as Integer, ByRef _
destSizeNeeded as Integer )

Const COMPRESSION_FORMAT_LZNT1 = &h2
dim neededSize as Integer
dim ret as new MemoryBlock( bufferSize )

RtlDecompressBuffer( COMPRESSION_FORMAT_LZNT1, ret, ret.Size, data, data.Size, neededSize )

ret.Size = neededSize

return ret

#else

#pragma unused data
#pragma unused bufferSize

#endif
End Function

You might have a look on this: https://forum.xojo.com/18130-native-unzip-on-windows.

How to set the options, you will find here: https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866(v=vs.85).aspx

I had a look and it works.
Still I’d prefer code dealing directly with strings, without having to create a new folder and a new file.

It’s hard to be sure what is the problem because WFS is discarding the return value of RtlDecompressBuffer, which is the error code. (Very few Win32 external methods should ever be declared as subroutines; this is a gripe I’ve had about WFS since the days of Aaron Ballman: return values are important!)

Re-write the declare to return an integer, and then see what the error number says:

Soft Declare Function RtlDecompressBuffer Lib "ntdll" ( format as Integer, destBuffer as Ptr, destLength as Integer, sourceBuffer as Ptr, sourceLength as Integer, ByRef destSizeNeeded as Integer ) As Integer
[...]
Dim error As Integer = RtlDecompressBuffer( COMPRESSION_FORMAT_LZNT1, ret, ret.Size, data, data.Size, neededSize )

If the error number is &hC0000242 (STATUS_BAD_COMPRESSION_BUFFER) then the output buffer is too small. Enlarge the buffer and call RtlDecompressBuffer again:

   Do
      error = RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, ret, ret.Size, data, data.Size, neededSize)
      If error = STATUS_BAD_COMPRESSION_BUFFER Then
        ret = New MemoryBlock(ret.Size * 2)
      End If
    Loop Until merror = 0

Since adding “as integer” returned a sintax error, I just raised ret to New MemoryBlock(ret.Size * 4), and everything went all right.
Thank you.

You also need to change Soft Declare Sub to Soft Declare Function.

Guess I was still half asleep.