Animated Cursor Resource (.ANI) File Format for Windows NT, March 1993 build. Derived by inspection of the several supplied .ANI files. April 4, 1993 Ross Berteig The .ANI file appears to consist of a sequence of named "tags", where a "tag" has the following structure: typedef struct tagANITAG { char atName[8]; DWORD atSize; BYTE atContents[0]; } ANITAG; The first two tags are nested, and the entire remaining content of the file is nested inside of the second tag. Without further examples, or a good guess at the meanings of "ASDFCONT" and "RAD CONT", it is difficult to see a reason for this nesting. The next few tags provide general information about the file, including a title string, and an author string. Microsoft seems to put a descriptive comment in the title string, and use the author string for a copyright message. These strings are displayed in the Cursors Control panel applet, below the listbox of cursors. It also appears that it is possible to crash CONTROL.EXE by putting more than 70 characters (or so... 70 works, 80 doesn't) in either of these strings. It would appear that the buffer was allocated on the stack, and that the tag size was not checked for buffer overflow before the tag was read. If CONTROL.EXE had access rights that the user didn't, this might represent a back-door of sorts. The real file header is found in an ANIHDATA tag. This tage contains a 36 byte structure which appears to be mostly zero in all of the examples. If considered as an array of DWORDS, the first element is the structure size, the second and third are both set to the number of frames of animation, and all but the last two are zero. The last one is always one in the examples (and if set to other than 1, the animation fails). The next to last field sets the duration of a single frame, in 1/60 of a second units. The ANIHDATA tag is followed by a series of ICONDATA tags. Each ICONDATA tag contains a verbatim copy of a Windows 3.1 .CUR file consisting of a single animation frame. The complete .ANI file can be sumarized as follows: "ASDFCONT" { "RAD CONT" { "TITLDATA" { "title text string" } "AUTHDATA" { "author text string" } "ANIHDATA" { .ANI Header Structure } "ICONDATA" { copy of a .CUR file } "ICONDATA" { copy of a .CUR file } . . . } } To simplify the construction of .ANI files, I have implemented a simple compiler, AC. AC is driven by a project file which allows for the title and author strings and frame rate to be set, and the listing of the .CUR files to include for the individual frames. Animation project files are assumed to have the suffix .APJ, and are made up of two sections. The first section is the [Options] section, which contains settings global to the animation. The second section is the [Frames] section, which contains a list of the .CUR files to be included. All of the header fields (aside from the frame rate) will be initialized automatically by AC. In particular, both of the fields that appear to contain a count of the frames will contain copies of the actual count of frame files named in the [Frames] section. The syntax is similar to that used by WIN.INI, and the input is in fact parsed by GetPrivateProfileString(), so all of the usual conventions apply. Sections other than [Options] and [Frames] will be ignored, as will blank lines, and lines beginning with a semicolon. Due to a quirk of the GetPrivateProfile...() functions, the frames are listed one per line, as the values for any names in the [Frames] section. A sample .APJ file that produces an .ANI file with 2 frames at a rate of 6 frames/sec would look like the following: [Options] Title=Sample Animation Project Author=John Doe, Copyright. Delay=10 [Frames] x=frame1.cur x=frame2.cur Version 1.1 of AC limits the size of the Title and Author strings so as to avoid the stack overflow bug in control.exe. In addition, a string tag called LICENSE can be added to an .ANI file to hold any additional copyright or license text. This string is unlimited, and will not be displayed by control.exe.