TABLE OF CONTENTS xpkmaster.library/--general-- xpkmaster.library/--replacements-- xpkmaster.library/--semaphore-- xpkmaster.library/--general-- xpkmaster.library/--general-- THE PREFERENCES IDEA In version 4 of xpkmaster.library a preferences system has been added to support file type depending packing. The implementation in master library is done by a semaphore mechanism (see below for this). Some additional tools are provided to handle the preferences. - XpkMaster - a normal SYS:Prefs/ preferences program. - XpkMasterPrefs - an IPrefs like support for the preferences. WHEN PREFERENCES ARE USED The preferences are used, when no (XPK_Preferences, FALSE) is passed. One of the Semaphore installing programs has to be started before, as xpkmaster.library only calls the semaphore and no files. The preferences pack happens when you call XpkPack and the XPK_PackMethod tag data contains packmethod "USER". THE PREFERENCES FORMAT The preferences are normal IFF PREF files, with a PRHD chunk containing information like the file version and XPKT and XPKM chunks with settings relevant to xpk. The structure of these hunks are defined in as struct XpkMainPrefs and struct XpkTypePrefs. These seem to be the first chunks containing pointers, therefore I will describe the format below. IFF POINTERS In memory a pointer is a 32 bit variable holding the address of another variable it refers to. A pointer of value 0 points to the start of memory. The same system is used for pointers in xpk prefs files. In the prefs files, ANY pointer refers relative to the first byte after the size information of the current chunk. So saving of a chunk goes following steps: - allocate a area of memory to hold all data - copy the main structure (either XpkTypePrefs or XpkMainPrefs) to the start of this area - copy all other data behind the main structure and set all pointers to point to the new place in this area. - now subtract the start address of the memory from all pointers The last two steps can be done in one. For examples how to do this, see the sources in Prefs directory of xpk_Source.lha archive. Loading needs following steps: - load the file into a buffer of chunk size - add address of memory area to all pointer values - repeat this for all sub structures, you created the real address a step before. (In XpkTypePrefs prefs are pointers to XpkTypeData which point to strings --> 3 different levels to correct, each after each other.) xpkmaster.library/--replacements-- xpkmaster.library/--replacements-- MAKING YOUR OWN PREFERENCES The preferences structure of xpkmaster.library is very open. Only a few fields of the semaphore (see below) are accessed by the master library directly. The preference files will never be accessed by the master library. So it is possible to replace the preferences system completely with an totally different one (may be depending on one of the file identifying libraries). You only have to make a program to build a public semaphore with exact the same name as the standard one and the same semaphore structure and set following fields: sem->xps_Version Set to version of your structure (for future enhancements). sem->xps_PrefsType Any ULONG value defining your preferences type. Try to use a value not used by another system. sem->ps_PrefsData Here you may store a pointer to private data. This data is not read by xpkmaster.library. sem->xps_MainPrefs Pointer to default preferences. When this is set to zero, internally defaults are used. sem->xps_RecogSize Size of the file buffer you need for finding the right packer. sem->xps_RecogFunc Pointer to the function scanning for the right packer. See below for more information. sem->xps_ProgressFunc This is a normal progress hook function, which is called, when the user selects XPK_ChunkReport. This function is not required. sem->xps_MasterTask This a pointer the the task structure of the semaphore installer. The installer task has to quit, when it gets a SIGBREAKF_CTRL_C signal! xpkmaster.library/--semaphore-- xpkmaster.library/--semaphore-- SEMAPHORE GENERAL Semaphores are a way to allow multitasking friendly access to public data structures. You get access following way: Forbid(); if((sem = (struct XpkPrefsSemaphore *) FindSemaphore(XPKPREFSSEMNAME))) ObtainSemaphoreShared((struct SignalSemaphore *) sem); Permit(); Now you either own it, or it does not exist. Do not forget to check if sem is zero after this piece of code. If not, you can READ all documented fields of the semaphore now. (If you want to write, use ObtainSemaphore() instead). There are some other methods for access. See programming manuals for these. After work you have to free the semaphore by calling ReleaseSemaphore((struct SignalSemaphore *) sem); THE XPKMASTER PREFERENCES SEMAPHORE The structure of this semaphore is described in xpk/xpkprefs.h. Most of the fields are not accessed by xpkmaster.library. This semaphore is public, so you may read all data of it, but because the stuff is done by xpkmaster.library there should be no need to do so. Writing to the semaphore is allowed too, but should never happen. See xpk/xpkprefs.h to get conditions. The most important part of the semaphore are the fields xps_RecogSize and xps_RecogFunc. xps_RecogSize is the size of the buffer needed by xps_RecogFunc to find out the filetype. xps_RecogFunc is a function to find out the filetype of a file and to return the specific packer type for this file. THE RECOG FUNCTION INPUTS - A pointer to a buffer holding the beginning of the file is passed in register A0. - In register A1 the filename of the file is passed. This may be zero, because in some cases xpkmaster.library does not have the filename. - In register A2 a tag list is passed with additionally information, f.e. XPK_PackMode for defining better user select abilities and XPK_FileName wich may be used for displaying the name in own requesters or in chunkhooks. When you do packing in the Recog function then pass XPK_FileName as data. - In register D0 the size of buffer in A0 is passed. This should equal xps_RecogSize or when the file is shorter be the file length. - In register D1 the complete file size is passed. OUTPUT - Register D0 passes a pointer to a struct XpkTypeData holding the needed information for packing. If no information, return should be zero. - If return value equals -1 (0xFFFFFFFF), the function will be called again with buffer size equal to file size. Do not return -1 when buffer size already equals file size. - When 0 is returned the data from xps_MainPrefs or the internal defaults are used. NOTE - The Recog function should take the filename only as additional feature. If no filename is given the filename check cannot take place (it is always true). - For callers: The returned data is valid only as long as you obtain the semaphore. - When xpkmaster.library should free the XpkTypeData stuff, then set the fields xtd_Memory and xtd_MemorySize. xpkmaster.library calls then FreeMem(t->xtd_Memory, t->xtd_MemorySize);. The memory must not point to the XpkTypeData structure! This is useful, when the type is not in a list, but is created. NOTE: The memory area may hold passwords or other data.