| /* |
| * Dump a shortcut (lnk) file |
| * |
| * Copyright 2005 Mike McCormack |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include "config.h" |
| #include "wine/port.h" |
| #include "winedump.h" |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #ifdef HAVE_UNISTD_H |
| # include <unistd.h> |
| #endif |
| #ifdef HAVE_SYS_TYPES_H |
| # include <sys/types.h> |
| #endif |
| #include <fcntl.h> |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| |
| #include "pshpack1.h" |
| |
| typedef enum { |
| SLDF_HAS_ID_LIST = 0x00000001, |
| SLDF_HAS_LINK_INFO = 0x00000002, |
| SLDF_HAS_NAME = 0x00000004, |
| SLDF_HAS_RELPATH = 0x00000008, |
| SLDF_HAS_WORKINGDIR = 0x00000010, |
| SLDF_HAS_ARGS = 0x00000020, |
| SLDF_HAS_ICONLOCATION = 0x00000040, |
| SLDF_UNICODE = 0x00000080, |
| SLDF_FORCE_NO_LINKINFO = 0x00000100, |
| SLDF_HAS_EXP_SZ = 0x00000200, |
| SLDF_RUN_IN_SEPARATE = 0x00000400, |
| SLDF_HAS_LOGO3ID = 0x00000800, |
| SLDF_HAS_DARWINID = 0x00001000, |
| SLDF_RUNAS_USER = 0x00002000, |
| SLDF_HAS_EXP_ICON_SZ = 0x00004000, |
| SLDF_NO_PIDL_ALIAS = 0x00008000, |
| SLDF_FORCE_UNCNAME = 0x00010000, |
| SLDF_RUN_WITH_SHIMLAYER = 0x00020000, |
| SLDF_FORCE_NO_LINKTRACK = 0x00040000, |
| SLDF_ENABLE_TARGET_METADATA = 0x00080000, |
| SLDF_DISABLE_KNOWNFOLDER_RELATIVE_TRACKING = 0x00200000, |
| SLDF_RESERVED = 0x80000000, |
| } SHELL_LINK_DATA_FLAGS; |
| |
| #define EXP_SZ_LINK_SIG 0xa0000001 |
| #define EXP_SPECIAL_FOLDER_SIG 0xa0000005 |
| #define EXP_DARWIN_ID_SIG 0xa0000006 |
| #define EXP_SZ_ICON_SIG 0xa0000007 |
| #define EXP_PROPERTYSTORAGE_SIG 0xa0000009 |
| |
| typedef struct tagDATABLOCKHEADER |
| { |
| DWORD cbSize; |
| DWORD dwSignature; |
| } DATABLOCK_HEADER; |
| |
| typedef struct _LINK_HEADER |
| { |
| DWORD dwSize; /* 0x00 size of the header - 0x4c */ |
| GUID MagicGuid; /* 0x04 is CLSID_ShellLink */ |
| DWORD dwFlags; /* 0x14 describes elements following */ |
| DWORD dwFileAttr; /* 0x18 attributes of the target file */ |
| FILETIME Time1; /* 0x1c */ |
| FILETIME Time2; /* 0x24 */ |
| FILETIME Time3; /* 0x2c */ |
| DWORD dwFileLength; /* 0x34 File length */ |
| DWORD nIcon; /* 0x38 icon number */ |
| DWORD fStartup; /* 0x3c startup type */ |
| DWORD wHotKey; /* 0x40 hotkey */ |
| DWORD Unknown5; /* 0x44 */ |
| DWORD Unknown6; /* 0x48 */ |
| } LINK_HEADER, * PLINK_HEADER; |
| |
| typedef struct tagLINK_SZ_BLOCK |
| { |
| DWORD size; |
| DWORD magic; |
| CHAR bufA[MAX_PATH]; |
| WCHAR bufW[MAX_PATH]; |
| } LINK_SZ_BLOCK; |
| |
| typedef struct tagLINK_PROPERTYSTORAGE_GUID |
| { |
| DWORD size; |
| DWORD magic; |
| GUID fmtid; |
| } LINK_PROPERTYSTORAGE_GUID; |
| |
| typedef struct tagLINK_PROPERTYSTORAGE_VALUE |
| { |
| DWORD size; |
| DWORD pid; |
| BYTE unknown8; |
| DWORD vt; |
| DWORD unknown25; |
| } LINK_PROPERTYSTORAGE_VALUE; |
| |
| typedef struct _LOCATION_INFO |
| { |
| DWORD dwTotalSize; |
| DWORD dwHeaderSize; |
| DWORD dwFlags; |
| DWORD dwVolTableOfs; |
| DWORD dwLocalPathOfs; |
| DWORD dwNetworkVolTableOfs; |
| DWORD dwFinalPathOfs; |
| } LOCATION_INFO; |
| |
| typedef struct _LOCAL_VOLUME_INFO |
| { |
| DWORD dwSize; |
| DWORD dwType; |
| DWORD dwVolSerial; |
| DWORD dwVolLabelOfs; |
| } LOCAL_VOLUME_INFO; |
| |
| typedef struct _NETWORK_VOLUME_INFO |
| { |
| DWORD dwSize; |
| DWORD dwUnkown1; |
| DWORD dwShareNameOfs; |
| DWORD dwReserved; |
| DWORD dwUnknown2; |
| } NETWORK_VOLUME_INFO; |
| |
| typedef struct |
| { |
| DWORD cbSize; |
| DWORD dwSignature; |
| DWORD idSpecialFolder; |
| DWORD cbOffset; |
| } EXP_SPECIAL_FOLDER; |
| |
| typedef struct lnk_string_tag |
| { |
| unsigned short size; |
| union { |
| unsigned short w[1]; |
| unsigned char a[1]; |
| } str; |
| } lnk_string; |
| |
| #include "poppack.h" |
| |
| static unsigned offset; |
| |
| static const void* fetch_block(void) |
| { |
| const unsigned* u; |
| const void* ret; |
| |
| if (!(u = PRD(offset, sizeof(*u)))) return 0; |
| if ((ret = PRD(offset, *u))) offset += *u; |
| return ret; |
| } |
| |
| static const lnk_string* fetch_string(int unicode) |
| { |
| const unsigned short* s; |
| unsigned short len; |
| const void* ret; |
| |
| if (!(s = PRD(offset, sizeof(*s)))) return 0; |
| len = *s * (unicode ? sizeof(WCHAR) : sizeof(char)); |
| if ((ret = PRD(offset, sizeof(*s) + len))) offset += sizeof(*s) + len; |
| return ret; |
| } |
| |
| |
| static int dump_pidl(void) |
| { |
| const lnk_string *pidl; |
| int i, n = 0, sz = 0; |
| |
| pidl = fetch_string(FALSE); |
| if (!pidl) |
| return -1; |
| |
| printf("PIDL\n"); |
| printf("----\n\n"); |
| |
| while(sz<pidl->size) |
| { |
| const lnk_string *segment = (const lnk_string*) &pidl->str.a[sz]; |
| |
| if(!segment->size) |
| break; |
| sz+=segment->size; |
| if(sz>pidl->size) |
| { |
| printf("bad pidl\n"); |
| break; |
| } |
| n++; |
| printf("segment %d (%2d bytes) : ",n,segment->size); |
| for(i=0; i<segment->size; i++) |
| printf("%02x ",segment->str.a[i]); |
| printf("\n"); |
| } |
| printf("\n"); |
| |
| return 0; |
| } |
| |
| static int dump_string(const char *what, int unicode) |
| { |
| const lnk_string *data; |
| unsigned sz; |
| |
| data = fetch_string(unicode); |
| if (!data) |
| return -1; |
| printf("%s : ", what); |
| sz = data->size; |
| if (unicode) |
| while (sz) printf("%c", data->str.w[data->size - sz--]); |
| else |
| while (sz) printf("%c", data->str.a[data->size - sz--]); |
| printf("\n"); |
| |
| return 0; |
| } |
| |
| static int dump_location(void) |
| { |
| const LOCATION_INFO *loc; |
| const char *p; |
| |
| loc = fetch_block(); |
| if (!loc) |
| return -1; |
| p = (const char*)loc; |
| |
| printf("Location\n"); |
| printf("--------\n\n"); |
| printf("Total size = %d\n", loc->dwTotalSize); |
| printf("Header size = %d\n", loc->dwHeaderSize); |
| printf("Flags = %08x\n", loc->dwFlags); |
| |
| /* dump information about the local volume the link points to */ |
| printf("Local volume ofs = %08x ", loc->dwVolTableOfs); |
| if (loc->dwVolTableOfs && |
| loc->dwVolTableOfs + sizeof(LOCAL_VOLUME_INFO) < loc->dwTotalSize) |
| { |
| const LOCAL_VOLUME_INFO *vol = (const LOCAL_VOLUME_INFO *)&p[loc->dwVolTableOfs]; |
| |
| printf("size %d type %d serial %08x label %d ", |
| vol->dwSize, vol->dwType, vol->dwVolSerial, vol->dwVolLabelOfs); |
| if(vol->dwVolLabelOfs) |
| printf("(\"%s\")", &p[loc->dwVolTableOfs + vol->dwVolLabelOfs]); |
| } |
| printf("\n"); |
| |
| /* dump information about the network volume the link points to */ |
| printf("Network volume ofs = %08x ", loc->dwNetworkVolTableOfs); |
| if (loc->dwNetworkVolTableOfs && |
| loc->dwNetworkVolTableOfs + sizeof(NETWORK_VOLUME_INFO) < loc->dwTotalSize) |
| { |
| const NETWORK_VOLUME_INFO *vol = (const NETWORK_VOLUME_INFO *)&p[loc->dwNetworkVolTableOfs]; |
| |
| printf("size %d name %d ", vol->dwSize, vol->dwShareNameOfs); |
| if(vol->dwShareNameOfs) |
| printf("(\"%s\")", &p[loc->dwNetworkVolTableOfs + vol->dwShareNameOfs]); |
| } |
| printf("\n"); |
| |
| /* dump out the path the link points to */ |
| printf("LocalPath ofs = %08x ", loc->dwLocalPathOfs); |
| if( loc->dwLocalPathOfs && (loc->dwLocalPathOfs < loc->dwTotalSize) ) |
| printf("(\"%s\")", &p[loc->dwLocalPathOfs]); |
| printf("\n"); |
| |
| printf("Net Path ofs = %08x\n", loc->dwNetworkVolTableOfs); |
| printf("Final Path = %08x ", loc->dwFinalPathOfs); |
| if( loc->dwFinalPathOfs && (loc->dwFinalPathOfs < loc->dwTotalSize) ) |
| printf("(\"%s\")", &p[loc->dwFinalPathOfs]); |
| printf("\n"); |
| printf("\n"); |
| |
| return 0; |
| } |
| |
| static const unsigned char table_dec85[0x80] = { |
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff, |
| 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17, |
| 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, |
| 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36, |
| 0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46, |
| 0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff, |
| }; |
| |
| static int base85_to_guid( const char *str, LPGUID guid ) |
| { |
| DWORD i, val = 0, base = 1, *p; |
| unsigned char ch; |
| |
| p = (DWORD*) guid; |
| for( i=0; i<20; i++ ) |
| { |
| if( (i%5) == 0 ) |
| { |
| val = 0; |
| base = 1; |
| } |
| ch = str[i]; |
| if( ch >= 0x80 ) |
| return 0; |
| val += table_dec85[ch] * base; |
| if( table_dec85[ch] == 0xff ) |
| return 0; |
| if( (i%5) == 4 ) |
| p[i/5] = val; |
| base *= 85; |
| } |
| return 1; |
| } |
| |
| static int dump_special_folder_block(const DATABLOCK_HEADER* bhdr) |
| { |
| const EXP_SPECIAL_FOLDER *sfb = (const EXP_SPECIAL_FOLDER*)bhdr; |
| printf("Special folder block\n"); |
| printf("--------------------\n\n"); |
| printf("folder = 0x%04x\n", sfb->idSpecialFolder); |
| printf("offset = %d\n", sfb->cbOffset); |
| printf("\n"); |
| return 0; |
| } |
| |
| static int dump_sz_block(const DATABLOCK_HEADER* bhdr, const char* label) |
| { |
| const LINK_SZ_BLOCK *szp = (const LINK_SZ_BLOCK*)bhdr; |
| printf("String block\n"); |
| printf("-----------\n\n"); |
| printf("magic = %x\n", szp->magic); |
| printf("%s = %s\n", label, szp->bufA); |
| printf("\n"); |
| return 0; |
| } |
| |
| static int dump_darwin_id(const DATABLOCK_HEADER* bhdr) |
| { |
| const LINK_SZ_BLOCK *szp = (const LINK_SZ_BLOCK*)bhdr; |
| char comp_str[40]; |
| const char *feat, *comp, *prod_str, *feat_str; |
| GUID guid; |
| |
| printf("Advertise Info\n"); |
| printf("--------------\n\n"); |
| printf("msi string = %s\n", szp->bufA); |
| |
| if (base85_to_guid(szp->bufA, &guid)) |
| prod_str = get_guid_str(&guid); |
| else |
| prod_str = "?"; |
| |
| comp = &szp->bufA[20]; |
| feat = strchr(comp, '>'); |
| if (!feat) |
| feat = strchr(comp, '<'); |
| if (feat) |
| { |
| memcpy(comp_str, comp, feat - comp); |
| comp_str[feat-comp] = 0; |
| } |
| else |
| { |
| strcpy(comp_str, "?"); |
| } |
| |
| if (feat && feat[0] == '>' && base85_to_guid( &feat[1], &guid )) |
| feat_str = get_guid_str( &guid ); |
| else |
| feat_str = ""; |
| |
| printf(" product: %s\n", prod_str); |
| printf(" component: %s\n", comp_str ); |
| printf(" feature: %s\n", feat_str); |
| printf("\n"); |
| |
| return 0; |
| } |
| |
| static void dump_property_storage_value(const LINK_PROPERTYSTORAGE_VALUE *lnk_value_hdr, |
| DWORD data_size) |
| { |
| int got_terminator = 0, i, value_size; |
| const unsigned char *value; |
| |
| while (data_size >= sizeof(DWORD)) |
| { |
| if (!lnk_value_hdr->size) |
| { |
| got_terminator = 1; |
| break; |
| } |
| |
| if (lnk_value_hdr->size > data_size || lnk_value_hdr->size < sizeof(*lnk_value_hdr)) |
| { |
| printf(" size: %d (invald)\n", lnk_value_hdr->size); |
| return; |
| } |
| |
| printf(" pid: %d\n", lnk_value_hdr->pid); |
| printf(" unknown8: %d\n", lnk_value_hdr->unknown8); |
| printf(" vartype: %d\n", lnk_value_hdr->vt); |
| printf(" unknown25: %d\n", lnk_value_hdr->unknown25); |
| |
| value_size = lnk_value_hdr->size - sizeof(*lnk_value_hdr); |
| value = (const unsigned char*)(lnk_value_hdr+1); |
| |
| printf(" value (%2d bytes) : ",value_size); |
| for(i=0; i<value_size; i++) |
| printf("%02x ",value[i]); |
| printf("\n\n"); |
| |
| data_size -= lnk_value_hdr->size; |
| lnk_value_hdr = (void*)((char*)lnk_value_hdr + lnk_value_hdr->size); |
| } |
| |
| if (!got_terminator) |
| printf(" missing terminator!\n"); |
| } |
| |
| static int dump_property_storage(const DATABLOCK_HEADER* bhdr) |
| { |
| int data_size; |
| const LINK_PROPERTYSTORAGE_GUID *lnk_guid_hdr; |
| int got_terminator = 0; |
| |
| printf("Property Storage\n"); |
| printf("--------------\n\n"); |
| |
| data_size=bhdr->cbSize-sizeof(*bhdr); |
| |
| lnk_guid_hdr=(void*)((const char*)bhdr+sizeof(*bhdr)); |
| |
| while (data_size >= sizeof(DWORD)) |
| { |
| if (!lnk_guid_hdr->size) |
| { |
| got_terminator = 1; |
| break; |
| } |
| |
| if (lnk_guid_hdr->size > data_size || lnk_guid_hdr->size < sizeof(*lnk_guid_hdr)) |
| { |
| printf("size: %d (invald)\n", lnk_guid_hdr->size); |
| return 1; |
| } |
| |
| if (lnk_guid_hdr->magic != 0x53505331) |
| printf("magic: %x\n", lnk_guid_hdr->magic); |
| |
| printf("fmtid: %s\n", get_guid_str(&lnk_guid_hdr->fmtid)); |
| |
| dump_property_storage_value((void*)(lnk_guid_hdr + 1), lnk_guid_hdr->size - sizeof(*lnk_guid_hdr)); |
| |
| data_size -= lnk_guid_hdr->size; |
| |
| lnk_guid_hdr = (void*)((char*)lnk_guid_hdr + lnk_guid_hdr->size); |
| } |
| |
| if (!got_terminator) |
| printf("missing terminator!\n"); |
| |
| printf("\n"); |
| |
| return 0; |
| } |
| |
| static int dump_raw_block(const DATABLOCK_HEADER* bhdr) |
| { |
| int data_size; |
| |
| printf("Raw Block\n"); |
| printf("---------\n\n"); |
| printf("size = %d\n", bhdr->cbSize); |
| printf("magic = %x\n", bhdr->dwSignature); |
| |
| data_size=bhdr->cbSize-sizeof(*bhdr); |
| if (data_size > 0) |
| { |
| int i; |
| const unsigned char *data; |
| |
| printf("data = "); |
| data=(const unsigned char*)bhdr+sizeof(*bhdr); |
| while (data_size > 0) |
| { |
| for (i=0; i < 16; i++) |
| { |
| if (i < data_size) |
| printf("%02x ", data[i]); |
| else |
| printf(" "); |
| } |
| for (i=0; i < data_size && i < 16; i++) |
| printf("%c", (data[i] >= 32 && data[i] < 128 ? data[i] : '.')); |
| printf("\n"); |
| data_size-=16; |
| if (data_size <= 0) |
| break; |
| data+=16; |
| printf(" "); |
| } |
| } |
| printf("\n"); |
| |
| return 1; |
| } |
| |
| static const GUID CLSID_ShellLink = {0x00021401L, 0, 0, {0xC0,0,0,0,0,0,0,0x46}}; |
| |
| enum FileSig get_kind_lnk(void) |
| { |
| const LINK_HEADER* hdr; |
| |
| hdr = PRD(0, sizeof(*hdr)); |
| if (hdr && hdr->dwSize == sizeof(LINK_HEADER) && |
| !memcmp(&hdr->MagicGuid, &CLSID_ShellLink, sizeof(GUID))) |
| return SIG_LNK; |
| return SIG_UNKNOWN; |
| } |
| |
| void lnk_dump(void) |
| { |
| const LINK_HEADER* hdr; |
| const DATABLOCK_HEADER* bhdr; |
| DWORD dwFlags; |
| |
| offset = 0; |
| hdr = fetch_block(); |
| if (!hdr) |
| return; |
| |
| printf("Header\n"); |
| printf("------\n\n"); |
| printf("Size: %04x\n", hdr->dwSize); |
| printf("GUID: %s\n", get_guid_str(&hdr->MagicGuid)); |
| |
| printf("FileAttr: %08x\n", hdr->dwFileAttr); |
| printf("FileLength: %08x\n", hdr->dwFileLength); |
| printf("nIcon: %d\n", hdr->nIcon); |
| printf("Startup: %d\n", hdr->fStartup); |
| printf("HotKey: %08x\n", hdr->wHotKey); |
| printf("Unknown5: %08x\n", hdr->Unknown5); |
| printf("Unknown6: %08x\n", hdr->Unknown6); |
| |
| /* dump out all the flags */ |
| printf("Flags: %04x ( ", hdr->dwFlags); |
| dwFlags=hdr->dwFlags; |
| #define FLAG(x) do \ |
| { \ |
| if (dwFlags & SLDF_##x) \ |
| { \ |
| printf("%s ", #x); \ |
| dwFlags&=~SLDF_##x; \ |
| } \ |
| } while (0) |
| FLAG(HAS_ID_LIST); |
| FLAG(HAS_LINK_INFO); |
| FLAG(HAS_NAME); |
| FLAG(HAS_RELPATH); |
| FLAG(HAS_WORKINGDIR); |
| FLAG(HAS_ARGS); |
| FLAG(HAS_ICONLOCATION); |
| FLAG(UNICODE); |
| FLAG(FORCE_NO_LINKINFO); |
| FLAG(HAS_EXP_SZ); |
| FLAG(RUN_IN_SEPARATE); |
| FLAG(HAS_LOGO3ID); |
| FLAG(HAS_DARWINID); |
| FLAG(RUNAS_USER); |
| FLAG(HAS_EXP_ICON_SZ); |
| FLAG(NO_PIDL_ALIAS); |
| FLAG(FORCE_UNCNAME); |
| FLAG(RUN_WITH_SHIMLAYER); |
| FLAG(FORCE_NO_LINKTRACK); |
| FLAG(ENABLE_TARGET_METADATA); |
| FLAG(DISABLE_KNOWNFOLDER_RELATIVE_TRACKING); |
| FLAG(RESERVED); |
| #undef FLAG |
| if (dwFlags) |
| printf("+%04x", dwFlags); |
| printf(")\n"); |
| |
| printf("Length: %04x\n", hdr->dwFileLength); |
| printf("\n"); |
| |
| if (hdr->dwFlags & SLDF_HAS_ID_LIST) |
| dump_pidl(); |
| if (hdr->dwFlags & SLDF_HAS_LINK_INFO) |
| dump_location(); |
| if (hdr->dwFlags & SLDF_HAS_NAME) |
| dump_string("Description", hdr->dwFlags & SLDF_UNICODE); |
| if (hdr->dwFlags & SLDF_HAS_RELPATH) |
| dump_string("Relative path", hdr->dwFlags & SLDF_UNICODE); |
| if (hdr->dwFlags & SLDF_HAS_WORKINGDIR) |
| dump_string("Working directory", hdr->dwFlags & SLDF_UNICODE); |
| if (hdr->dwFlags & SLDF_HAS_ARGS) |
| dump_string("Arguments", hdr->dwFlags & SLDF_UNICODE); |
| if (hdr->dwFlags & SLDF_HAS_ICONLOCATION) |
| dump_string("Icon path", hdr->dwFlags & SLDF_UNICODE); |
| |
| bhdr=fetch_block(); |
| while (bhdr) |
| { |
| if (!bhdr->cbSize) |
| break; |
| switch (bhdr->dwSignature) |
| { |
| case EXP_SZ_LINK_SIG: |
| dump_sz_block(bhdr, "exp.link"); |
| break; |
| case EXP_SPECIAL_FOLDER_SIG: |
| dump_special_folder_block(bhdr); |
| break; |
| case EXP_SZ_ICON_SIG: |
| dump_sz_block(bhdr, "icon"); |
| break; |
| case EXP_DARWIN_ID_SIG: |
| dump_darwin_id(bhdr); |
| break; |
| case EXP_PROPERTYSTORAGE_SIG: |
| dump_property_storage(bhdr); |
| break; |
| default: |
| dump_raw_block(bhdr); |
| } |
| bhdr=fetch_block(); |
| } |
| } |