#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char byte;
struct Compound_Binary_File_Header
{
byte compound_file_id[8]; //0 8 Compound document file identifier: D0 CF 11 E0 A1 B1 1A E1
byte class_id[16]; //8 16 Unique identifier (UID) of this file, class id (set with WriteClassStg, retrieved with GetClassFile/ReadClassStg)
byte minor_version[2]; //24 2 minor version number of the file format (most used is 003EH)
byte major_version[2]; //26 2 major version number of the file format (most used is 0003H)
byte byte_order[2]; //28 2 Byte order identifier :FEH FFH = Little-Endian FFH FEH = Big-Endian
byte size_of_a_master_sector[2]; //30 2 Size of a sector in the compound document file in power-of-two (ssz), real sector size is sec_size = 2ssz bytes (most used value is 9 which means 512 bytes, minimum value is 7 which means 128 bytes)
byte size_of_a_short_sector[2]; //32 2 Size of a short-sector in the short-stream container stream in power-of-two (sssz), real short-sector size is short_sec_size = 2sssz bytes (most used value is 6 which means 64 bytes, maximum value is sector size ssz, see above)
byte reserved[2]; //34 2 Not used
byte reserved1[4]; //36 4 Not used
byte reserved2[4]; //40 4 Not used
byte number_of_sector_SAT[4]; //44 4 Total number of sectors used for the sector allocation table
byte first_sector_of_directory_stream[4]; //48 4 SID of first sector of the directory stream, first sector in the Directory chain
byte signature[4]; //52 4 Not used, signature used for transactionin: must be zero. The reference implementation does not support transactioning
byte min_size_of_a_standard_stream[4]; //56 4 Minimum size of a standard stream (in bytes, most used size is 4096 bytes), streams smaller than this value are stored as short-streams
byte first_sector_of_short_sector_SSAT[4]; //60 4 SID of first sector of the short-sector allocation table, or –2 (End Of Chain SID) if not extant
byte total_number_of_short_sector_SSAT[4]; //64 4 Total number of sectors used for the short-sector allocation table
byte first_sector_of_master_sector_MSAT[4]; //68 4 SID of first sector of the master sector allocation table, or –2 (End Of Chain SID) if no additional sectors used
byte total_number_of_master_sector_MSAT[4]; //72 4 Total number of sectors used for the master sector allocation table
byte first_109_master_sector_MSAT[436]; //76 436 First part of the master sector allocation table containing 109 SIDs
} ;
typedef enum tagSTGTY
{
TGTY_INVALID = 0,
STGTY_STORAGE = 1,
STGTY_STREAM = 2,
STGTY_LOCKBYTES = 3,
STGTY_PROPERTY = 4,
STGTY_ROOT = 5
} STGTY;
typedef enum tagDECOLOR //red-black tree 红黑树的颜色
{
DE_RED = 0,
DE_BLACK = 1
} DECOLOR;
struct Storage_Directory_Entry
{
byte name_of_entry[64]; // [000H,64] 64 bytes. The Element name in Unicode, like: "Root Entry"
byte length_of_entry[2]; // [040H,02] Length of the Element name in characters, not bytes
byte type_of_entry[1]; // [042H,01] Type of the entry: value taken from the STGTY enumeration
byte node_colour_of_entry[1]; // [043H,01] Value taken from DECOLOR enumeration. Node colour of the entry:00H = Red 01H = Black
byte did_of_left_sibling[4]; // [044H,04] SID of the left-sibling of this entry in the directory tree, DID of the left child node inside the red-black tree of all direct members of the parent storage (if this entry is a user storage or stream), –1 if there is no left child
byte did_of_right_sibling[4]; // [048H,04] SID of the right-sibling of this entry in the directory tree
byte did_of_child[4]; // [04CH,04] SID of the child acting as the root of all the children of this element (if _mse=STGTY_STORAGE)
byte class_id[16]; // [050H,16] CLSID of this storage (if _mse=STGTY_STORAGE)
byte user_flag[4]; // [060H,04] User flags of this storage (if _mse=STGTY_STORAGE)
byte time_st[8]; // [064H,16] Create/Modify time-stamps (if _mse=STGTY_STORAGE)
byte time_ed[8]; // [064H,16] Create/Modify time-stamps (if _mse=STGTY_STORAGE)
byte sid_of_first_sector[4]; // [074H,04] starting SECT of the stream (if _mse=STGTY_STREAM), SID of first sector or short-sector, if this entry refers to a stream, SID of first sector of the short-stream container stream, if this is the root storage entry, 0 otherwise
byte total_stream_size[4]; // [078H,04] size of stream in bytes (if _mse=STGTY_STREAM), Total stream size in bytes,
byte reserved[4]; // [07CH,04] Reserved for future use. Must be zero.
};
void _tmain(int argc, _TCHAR* argv[])
{
int i;
FILE *fd;
char *filename="test.xls";
char *testString[]={"order","gsdm","amount","1","6124","20180000.00"};
if( (fd=fopen(filename,"wb+"))==NULL )
{
printf("write file err\n");
exit(-1);
}
/*
struct Compound_Binary_File_Header xlsHeader;
memset(&xlsHeader,0,sizeof(struct Compound_Binary_File_Header));
unsigned char id[8]={0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1};
memcpy(xlsHeader.compound_file_id,id,8);
fwrite(&xlsHeader,sizeof(struct Compound_Binary_File_Header),1,fd);
*/
unsigned char XLSHEADER[8] = {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}; //0x00:复合文档的标识
unsigned char XLSHEADER2={0x00}; //0x8:16位:未定义
unsigned short int XLSSLAVEVERSION={0x3E}; //0x18:修订号 2位
unsigned short int XLSMAINVERSION={0x03}; //0x1A:版本号 2位
unsigned short int XLSCODINGL={0xFFFE}; //0x1C:字节排序方式 2位
unsigned short int XLSSectorSize={0x9}; //0x1E:扇区的大小:512字节 2位
unsigned short int XLSShortSectorSize={0x06}; //0x20:短扇区的大小:64字节 2位
unsigned char XLSUndefined1={0x00}; //0x22: 10位:未定义
unsigned int XLSSectorCount={0x1}; //0x2c: Sector总数 4位
unsigned int XLSFirstSectorId={0x19}; //0x30: Directory Sector的SID 4位
unsigned int XLSUndefined2={0x00}; //0x34: 4位:未定义
unsigned int XLSStreamSize={0x1000}; //0x38: 标准流大小:4096字节 4位 //暂定为512字节
unsigned int XLSShortSectorId={-2}; //0x3C:第一个短扇区Sector的SID 4位
unsigned int XLSShortSectorCount={0x00}; //0x40:短扇区Sector总数 4位
unsigned int XLSMSATID={-2}; //0x44:主扇区第一个Sector的SID 4位
unsigned int XLSMSATCount={0x00}; //0x48:主扇区Sector的总数 4位
unsigned int onlyBlockChainStartPos={0x18}; //0x4C:
int XLSZero2={-1};
unsigned char blockZero[512];
memset(blockZero,0,512);
fwrite(&XLSHEADER,8,1,fd);//复合文档的标识
for(int x=0;x<16;x++) fwrite(&XLSHEADER2,1,1,fd);//16位:未定义
fwrite(&XLSSLAVEVERSION,2,1,fd); //修订号
fwrite(&XLSMAINVERSION,2,1,fd); //版本号
fwrite(&XLSCODINGL,2,1,fd); //字节排序方式
fwrite(&XLSSectorSize,2,1,fd); //扇区的大小:512字节
fwrite(&XLSShortSectorSize,2,1,fd); //短扇区的大小:64字节
for(int x=0;x<10;x++) fwrite(&XLSUndefined1,1,1,fd); //10位:未定义
fwrite(&XLSSectorCount,4,1,fd); //Sector总数 4位
fwrite(&XLSFirstSectorId,4,1,fd); //第一个Sector的SID 4位
fwrite(&XLSUndefined2,4,1,fd); //4位:未定义
fwrite(&XLSStreamSize,4,1,fd); //标准流大小:4096字节 4位
fwrite(&XLSShortSectorId,4,1,fd); //第一个短扇区Sector的SID 4位
fwrite(&XLSShortSectorCount,4,1,fd); //短扇区Sector总数 4位
fwrite(&XLSMSATID,4,1,fd); //主扇区第一个Sector的SID 4位
fwrite(&XLSMSATCount,4,1,fd); //主扇区Sector的总数 4位
fwrite(&onlyBlockChainStartPos,4,1,fd); //blockChain开始位置,暂设为0x3:实际为(0x3+1)*512
for(i=0;i<108;i++) fwrite(&XLSZero2,4,1,fd);
unsigned short int streamFlag={0x809}; //stream开始标志
unsigned short int streamLen={0x10};
unsigned short int biffVersion={0x600};
unsigned short int workBookStreamVersion={0x5};
unsigned short int workSheetStreamVersion={0x10};
unsigned char xlsZero3={0x00};
unsigned short int xlsEOF={0x0a};
fwrite(&streamFlag,2,1,fd);
fwrite(&streamLen,2,1,fd);
fwrite(&biffVersion,2,1,fd);
fwrite(&workBookStreamVersion,2,1,fd);
for(int x=0;x<streamLen-4;x++) fwrite(&xlsZero3,1,1,fd);
unsigned short int userInter[8]={0xe1,0x2,0x4b0,0xc1,0x2,0x0,0xe2,0x0};
fwrite(&userInter,16,1,fd);
unsigned short int xlsBoundSheetFlag={0x85}; //sheet标志
unsigned short int xlsBoundSheetLen={0xe}; //暂设为0xe
unsigned int rec_offset={0x200}; //暂设为0x200
unsigned short int unknownOption={0x0};
char sheetName1[]="Sheet1";
unsigned short int sheetName1_len=strlen(sheetName1);
fwrite(&xlsBoundSheetFlag,2,1,fd);
fwrite(&xlsBoundSheetLen,2,1,fd);
fwrite(&rec_offset,4,1,fd);
fwrite(&unknownOption,2,1,fd);
fwrite(&sheetName1_len,2,1,fd);
fwrite(sheetName1,6,1,fd);
unsigned short int xlsSstFlag={0xfc}; //字符串sst标志
unsigned short int xlsSstLen=0;
unsigned int xlsZero4={0x0};
unsigned int uniqStrCount={0x6}; //length of testString[]
unsigned char option1={0x4}; ///[1]:1-Ascii,0-Unicode [4]:1-ExtendChars
unsigned int extendCharNum={0x10};
for(int x=0;x<6;x++)
{
//printf("%d:%s\n",strlen(testString[x]),testString[x]);
xlsSstLen+=(7+strlen(testString[x])+extendCharNum);
}
xlsSstLen+=8;
printf("%x\n",xlsSstLen);
fwrite(&xlsSstFlag,2,1,fd);
fwrite(&xlsSstLen,2,1,fd);
//fwrite(&xlsZero4,4,1,fd);
fwrite(&uniqStrCount,4,1,fd);
fwrite(&uniqStrCount,4,1,fd);
for(int x=0;x<6;x++)
{
unsigned short int charNums=0;
charNums=strlen(testString[x]);
fwrite(&charNums,2,1,fd);
fwrite(&option1,1,1,fd);
fwrite(&extendCharNum,4,1,fd);
fwrite(testString[x],strlen(testString[x]),1,fd);
for(int x=0;x<extendCharNum;x++) fwrite(&xlsZero4,1,1,fd);
}
/*
unsigned short int extSst[7]={0xff,0xa,0x8,0x0,0x6c8,0xc,0x0};
fwrite(&extSst,14,1,fd);
unsigned short int xlsBookInfo={0x863}; //Extra Book Info
unsigned short int xlsBookInfoLen={0x15};
unsigned short int xlsBookInfo2={0x863};
unsigned int xlsBookInfoCB={0x15};
unsigned char xlsBookInfoOpt={0xFE};
fwrite(&xlsBookInfo,2,1,fd);
fwrite(&xlsBookInfoLen,2,1,fd);
fwrite(&xlsBookInfo2,2,1,fd);
for(unsigned int x=0;x<10;x++) fwrite(&xlsZero4,1,1,fd);
fwrite(&xlsBookInfoCB,4,1,fd);
fwrite(&xlsZero4,4,1,fd);
fwrite(&xlsBookInfoOpt,1,1,fd);
*/
fwrite(&xlsEOF,2,1,fd);
int byteWrote=ftell(fd)%512;
for(int x=0;x<512-byteWrote;x++) fwrite(&xlsZero4,1,1,fd);
fwrite(&streamFlag,2,1,fd); //第一个sheet开始
fwrite(&streamLen,2,1,fd);
fwrite(&biffVersion,2,1,fd);
fwrite(&workSheetStreamVersion,2,1,fd);
//fwrite(&xlsZero4,4,1,fd);
for(int x=0;x<streamLen-4;x++) fwrite(&xlsZero3,1,1,fd);
/*
unsigned short int indexRecordFlag[2]={0x20B,0x14}; //0x20b
unsigned int indexRecord[5]={0x00,0x00,0x5,0x7E6,0x82E};
fwrite(&indexRecordFlag,4,1,fd);
fwrite(&indexRecord,20,1,fd);
unsigned short int defColWidthArea[3] ={0x55,0x2,0x8}; //宽度?
fwrite(defColWidthArea,6,1,fd);
*/
unsigned short int xlsDimensions={0x200}; //维度
unsigned short int xlsDimenLen={0xe};
unsigned int firstRow=0;
unsigned int lastRow=6;
unsigned short int firstCol=0;
unsigned short int lastCol=1;
fwrite(&xlsDimensions,2,1,fd);
fwrite(&xlsDimenLen,2,1,fd);
fwrite(&firstRow,4,1,fd);
fwrite(&lastRow,4,1,fd);
fwrite(&firstCol,2,1,fd);
fwrite(&lastCol,2,1,fd);
fwrite(&xlsZero4,2,1,fd);
unsigned short int sstLabel={0xfd}; //行、列字符串信息
unsigned short int sstLabelLen={0xa};
unsigned short int rowNum=0;
unsigned short int colNum=0;
unsigned short int xfIdx=0;
unsigned int sstIdx=0;
for(int x=0;x<uniqStrCount;x++)
{
fwrite(&sstLabel,2,1,fd);
fwrite(&sstLabelLen,2,1,fd);
rowNum=x;
fwrite(&rowNum,2,1,fd);
fwrite(&colNum,2,1,fd);
fwrite(&xfIdx,2,1,fd);
sstIdx=x;
fwrite(&sstIdx,4,1,fd);
}
fwrite(&xlsEOF,2,1,fd);
byteWrote=ftell(fd)%512;
for(int x=0;x<512-byteWrote;x++) fwrite(&xlsZero4,1,1,fd);
//workbook区,凑够8个block:
for(i=0;i<6;i++) fwrite(&blockZero,512,1,fd);
//SummaryInformation区,凑够8个block:
for(i=0;i<8;i++) fwrite(&blockZero,512,1,fd);
//DocumentSummaryInformation区,凑够8个block:
for(i=0;i<8;i++) fwrite(&blockZero,512,1,fd);
//blockChain:
unsigned int chain1=-3;
unsigned int chainEOF=-2;
char xlsFree=-1;
unsigned int chainTotal=0x1b;
chainTotal=chainTotal-3;
unsigned short int bl=512;
for(unsigned int x=1;x<chainTotal;x++)
{
if(x%8==0) fwrite(&chainEOF,4,1,fd);
else fwrite(&x,4,1,fd);
bl=bl-4;
}
fwrite(&chainEOF,4,1,fd);
fwrite(&chain1,4,1,fd);
fwrite(&chainEOF,4,1,fd);
for(int x=0;x<bl-12;x++) fwrite(&xlsFree,1,1,fd);
/* Storage_Directory_Entry : */
//Root:
wchar_t dir_root[64];
memset(dir_root,0,64);
wcscpy(dir_root,L"Root Entry");
fwrite(dir_root,64,1,fd);
unsigned short int dir_root_len=0x16;
unsigned char type_of_root=0x5;
unsigned char node_colour_of_entry=0x1;
unsigned int did_root[3]={-1,-1,2};
unsigned int rootSecPos=-2;
unsigned int rootSecSize=0x0;
fwrite(&dir_root_len,2,1,fd);
fwrite(&type_of_root,1,1,fd);
fwrite(&node_colour_of_entry,1,1,fd);
fwrite(&did_root,12,1,fd);
for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
fwrite(&rootSecPos,4,1,fd);
fwrite(&rootSecSize,4,1,fd);
fwrite(&xlsZero4,4,1,fd);
//Workbook:
wchar_t dir_wb[64];
memset(dir_wb,0,64);
wcscpy(dir_wb,L"Workbook");
fwrite(dir_wb,64,1,fd);
unsigned short int dir_wb_len=0x12;
unsigned char type_of_wb=0x2;
//unsigned char node_colour_of_entry=0x1;
unsigned int did_wb[3]={-1,-1,-1};
unsigned int wbSecPos=0;
unsigned int wbSecSize=0x1000;
fwrite(&dir_wb_len,2,1,fd);
fwrite(&type_of_wb,1,1,fd);
fwrite(&node_colour_of_entry,1,1,fd);
fwrite(&did_wb,12,1,fd);
for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
fwrite(&wbSecPos,4,1,fd);
fwrite(&wbSecSize,4,1,fd);
fwrite(&xlsZero4,4,1,fd);
//Summary:
wchar_t dir_sinfo[64];
memset(dir_sinfo,0,64);
wcscpy(dir_sinfo,L"\x5SummaryInformation");
fwrite(dir_sinfo,64,1,fd);
unsigned short int dir_sum_len=0x28;
unsigned char type_of_sum=0x2;
//unsigned char node_colour_of_entry=0x1;
unsigned int did_sum[3]={1,3,-1};
unsigned int sumSecPos=0x8;
unsigned int sumSecSize=0x1000;
fwrite(&dir_sum_len,2,1,fd);
fwrite(&type_of_sum,1,1,fd);
fwrite(&node_colour_of_entry,1,1,fd);
fwrite(&did_sum,12,1,fd);
for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
fwrite(&sumSecPos,4,1,fd);
fwrite(&sumSecSize,4,1,fd);
fwrite(&xlsZero4,4,1,fd);
//DocumentSummary:
wchar_t dir_dsinfo[64];
memset(dir_dsinfo,0,64);
wcscpy(dir_dsinfo,L"DocumentSummaryInformation");
fwrite(L"\x5",2,1,fd);
fwrite(dir_dsinfo,62,1,fd);
unsigned short int dir_dsum_len=0x38;
unsigned char type_of_dsum=0x2;
//unsigned char node_colour_of_entry=0x1;
unsigned int did_dsum[3]={-1,-1,-1};
unsigned int dsumSecPos=0x10;
unsigned int dsumSecSize=0x1000;
fwrite(&dir_dsum_len,2,1,fd);
fwrite(&type_of_dsum,1,1,fd);
fwrite(&node_colour_of_entry,1,1,fd);
fwrite(&did_dsum,12,1,fd);
for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
fwrite(&dsumSecPos,4,1,fd);
fwrite(&dsumSecSize,4,1,fd);
fwrite(&xlsZero4,4,1,fd);
fflush(fd);
fclose(fd);
system("pause");
}