7

Note: this question is about the Windows LZ functions, which are File Management Functions beginning with the prefix LZ: LZOpenFile, LZCopy, LZClose, etc. If Google isn't wrong, these are probably among the most poorly documented functions of the Windows API.

I'm trying to figure out what kind of files are actually suited for usage with the Windows LZ functions. The official documentation mentions "data that was compressed using Compress.exe", but the functions are also able to handle uncompressed files, in which case no decompression is applied.

Now, when I compress a file with the compress.exe utility from the resource kit (using either the -Z or -ZX switches), and then decompress it using the procedure described here, all I get is the source file unchanged, as if it were not compressed as expected. Even with a compressed file from the original Windows XP setup CD (those named with an underscore at the end in the i386 folder), I get the same result. Conclusion: no matter what file I try to decompress, I get it back unchanged.

The code I'm using is pretty straightforward, it basically reproduces the steps described in the MSDN article, so if I have a bug, I guess it must be somewhere else. But I'm still prone to thinking I'm just using the wrong input files. Does anyone have any experience with those LZ functions already? Here's my code in C++.

#include <iostream>
#include <Windows.h>

using namespace std;

int main(int argc, char ** argv) {
    OFSTRUCT ofs1, ofs2;
    INT hfSrc = -1, hfDest = -1;

    if (argc <= 2) {
        cerr << "Usage: LZTEST Source Destination";
        return 1;
    }
    __try {
        hfSrc = LZOpenFile(argv[1], &ofs1, OF_READ);
        if (hfSrc < 0) {
            cerr << "Error invoking LZOpenFile on source file: " << hfSrc;
            return 1;
        }
        hfDest = LZOpenFile(argv[2], &ofs2, OF_CREATE);
        if (hfDest < 0) {
            cerr << "Error invoking LZOpenFile on destination file: " << hfDest;
            return 1;
        }
        INT result = LZCopy(hfSrc, hfDest);
        if (result < 0) {
            cerr << "Error invoking LZCopy: " << result;
            return 1;
        }
    } __finally {
        if (hfSrc >= 0) LZClose(hfSrc);
        if (hfDest >= 0) LZClose(hfDest);
    }
    cout << "Success";
    return 0;
}
BenMorel
  • 34,448
  • 50
  • 182
  • 322
GOTO 0
  • 42,323
  • 22
  • 125
  • 158
  • 2
    I tried your sample code verbatim and it works fine for me. Make sure you're actually using it on a file compressed with `compress.exe`. The `LZCopy` function looks for a header (`SZDD\x88\xf0\x27\x33`) and will only uncompress if the input file begins with those 8 bytes. – Jonathan Potter Dec 31 '12 at 02:11
  • @JonathanPotter where did you find `compress.exe`? I was using the one from the Windows Server 2003 Resource Kit Tools, and that was the problem. – GOTO 0 Dec 31 '12 at 03:29
  • One option might be to grab a copy of VS6 and the accompanying MSDN docs and check there. Since they're significantly older (10+ years) there may be some information in there that will help you. – Captain Obvlious Jan 04 '13 at 14:08
  • @CaptainObvlious Unfortunately, the old MSDN docs don't seem to know better than the new docs. But thanks for the idea. – GOTO 0 Jan 04 '13 at 22:45
  • @JonathanPotter: I think there's an answer in that :) – Lightness Races in Orbit Jan 05 '13 at 14:44

2 Answers2

3

Try the compress.exe here with no options.

Unless you need to uncompress some old files, use DotNetZip instead.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Well, in fact some LZ functions are marked as obsolete, but not all of them. But anyway, these are supposed to handle just file decompression, not compression. I don't see the point in replacing them with anything else until someone can explain what they actually do. – GOTO 0 Dec 31 '12 at 00:15
  • Replacing them? Are they in some legacy code you're working on? – Mark Adler Dec 31 '12 at 01:10
  • 1
    I don't need and I don't want to replace them. Just looking for how to use them. Please, read the question. – GOTO 0 Dec 31 '12 at 01:17
  • I have read the question. It does not say why you're asking about these functions in the first place. If you don't need them, then why do you care? – Mark Adler Dec 31 '12 at 02:06
  • Wow, that worked! The link to `CP0982.EXE` is password protected, but I was able to find the file and extract `COMPRESS.EXE`. It's a 16-bit exe dated 1992! I'm not surprised my Windows XP files wouldn't get unpacked... should have had a look at those Windows 3.1 setup diskettes. Thank you and happy 2013. – GOTO 0 Dec 31 '12 at 03:18
  • Ah, ok. Didn't consider the bounty. – Mark Adler Dec 31 '12 at 06:18
  • @MarkAdler: "If you don't need them, then why do you care?" It doesn't matter. A question has been asked. On SO we answer questions. – Lightness Races in Orbit Jan 05 '13 at 14:45
  • It certainly does matter, since the application can affect the answer. – Mark Adler Jan 05 '13 at 17:20
  • I am asking this because I was considering to use these functions to automate a setup task. As it soon became clear, this wasn't going to be possible, I started wondering if I could use them to optimize some other aspects of the deploy process. Not the best bet, though. – GOTO 0 Jan 05 '13 at 22:14
  • As I said, if you are not decompressing legacy files, then you should not be using these functions. Use DotNetZip or other modern compression tools instead. – Mark Adler Jan 06 '13 at 01:54
2

I'm trying to figure out what kind of files are actually suited for usage with the Windows LZ functions.

The types of files you would typically use this on were your installation files that you were distributing on floppy disks. Back in the day, most of Microsoft's products were installed from floppy disks, and most of the files were compressed to save on the number of disks that had to be distributed for each customer.

You could generally tell what files were compressed on the floppy disks because the last letter of the extension was usually an underscore:

KEYBOARD.DR_
KEYVIEW.EX_
LANGDUT.DL_
LANGENG.DL_
LANGFRN.DL_
LANGGER.DL_
LANGSCA.DL_
LANGSPA.DL_
LMOUSE.CO_
LMOUSE.DR_
LVMD.38_
LZEXPAND.DL_
MMSOUND.DR_
MOUSE.DR_
MSC3BC2.DR_
MSCMOUSE.DR_

You could uncompress them using the EXPAND.EXE or the functions you reference.

GalacticJello
  • 11,235
  • 2
  • 25
  • 35
  • 1
    Yes, indeed I can't think of any better application scenarios for those APIs than unpacking some 20 years old installation files. – GOTO 0 Jan 04 '13 at 22:52