Solved

Urgent!! compound file

Posted on 2000-04-07
8
334 Views
Last Modified: 2011-09-20
Hi!

Would you please help me how to combine a few kinds of file:1.bmp 1.wav to a compound file ,I need to create two storage and each for bmp ,the other for .wav and then save files into storage accordingly.

I think I need to use StgCreatXXX() some like that but I dont know how indeed to implement in code,plz help me.

the files are under c:\\ ,using windows and please no MFC , would you please give me a sample?

Thanks a lot!!
 
0
Comment
Question by:bidr
  • 3
  • 3
  • 2
8 Comments
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
i didn't understand what exectlly do you want to do with those files

but for working with files you have the fstream class it will do all the work with files that you need

if i didn't understood your problem explain it to me
0
 

Author Comment

by:bidr
Comment Utility
I need to put all this files into a single compound file under seperate storages.
so,i need to create a compound file with two storage and each contain some files.
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
maybe i still didn't get it but i don't see your problem

take the fstream class open your two files read them into your prog
then create a theard file write the size in bytes of the BMP them write the bmp data itself then the same with WAV

you can use it for any files to stick them together

you should each time to write to the file the name of the file<them bmp>then
the size in bytes<of the bmp>
and then the same for all the next files you want to add
0
 
LVL 4

Expert Comment

by:wylliker
Comment Utility
ntdragon,

bidr is using Microsoft's COM Compound Files.


bidr,

You need to do something like this ...
(Don't copy this verbatim - off the top of my head)

Keep in mind the a Compound File is a File System within a single file - so I am using the familiar metaphor of Folders (think of them as subdirectories) for your storages.  Root would be similar to the root directory of a drive.

IStorage * Root;
IStorage * WAVFolder;
IStorage * BMPFolder;
IStream * WAVStream;
IStream * BMPStream;

// Open the compound file

StgOpenStorage(FileName, NULL, STGM_READ_WRITE | STGM_SHARE_DENY_WRITE | STGM_DIRECT, NULL, 0, &Root);

// Create the "folders" for WAVs and BMPs
Root->CreateStorage(WAVStorageName,STGM_CREATE | STGM_DIRECT,0, 0, &WAVFolder);

Root->CreateStorage(BMPStorageName,STGM_CREATE | STGM_DIRECT,0, 0, &BMPFolder);

// put BMPs and WAVs in the folders

// For each WAV file
WAVFolder->CreateStream(WAVFileName,STGM_CREATE | STGM_DIRECT,0,0, &WAVStream);

// to write to the stream

fp = fopen(WAVFileName, "rb");
while(!feof(fp))
{
   BytesRead = fread(Buffer, 1, BUFFER_LEN, fp);
   if(BytesRead)
     WAVStream->Write(Buffer, BytesRead, &BytesWritten);
}
fclose(fp)

// close the stream
WAVStream->Release();

// close the "folder"
WAVFolder->Release();

// For each BMP file
BMPFolder->CreateStream(BMPFileName,STGM_CREATE | STGM_DIRECT,0,0, &BMPStream);

// write to stream

fp = fopen(BMPFileName, "rb");
while(!feof(fp))
{
   BytesRead = fread(Buffer, 1, BUFFER_LEN, fp);
   if(BytesRead)
     BMPStream->Write(Buffer, BytesRead, &BytesWritten);
}
fclose(fp)

// Close the stream
BMPStream->Release();

// close the "folder"
BMPFolder->Release();

// Close the compound file
Root->Release();



I had used C file reading in the above use whatever method you prefer - the idea with streams is that when writing them you need to pass a Buffer, it's length and a variable for the IStream to return how many bytes were actually written.

Here is the IStream::Write function from the Docs

HRESULT Write(
  void const* pv,  //Address of buffer from which stream is written
  ULONG cb,        //Specifies the number of bytes to write
  ULONG * pcbWritten
                   //Specifies the actual number of bytes written
);
 

You will have to add error checking, etc.

Also note that I used DIRECT instead of TRANSACT - if you need the compound file to be transactional then it gets a little more involved.

One more thing - calling Release() on a Storage or Stream closes it.



A suggestion ...

Get Inside OLE2 by Kraig Brockschmidt.
He has a full section devoted to Compound Files .



0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:bidr
Comment Utility
Thank!!

1:would you tell me how to specify storage and stream name ?
I use "somename" but it 's wrong.

2:Would you plz tell me how to translate to c++ ?
fp = fopen(BMPFileName, "rb");
while(!feof(fp))
{
   BytesRead = fread(Buffer, 1, BUFFER_LEN, fp);
   if(BytesRead)
     BMPStream->Write(Buffer, BytesRead, &BytesWritten);
}
fclose(fp)

I will give you more points later after I do excercise ,thank you very much!!!!
0
 
LVL 4

Accepted Solution

by:
wylliker earned 57 total points
Comment Utility
You can use the actual file name as the name of each of the streams or you can give it a friendlier name, if it is going to be displayed back to a user at some point.  For the storages just use a "good" name.

The name part of storages and streams are just character strings - again no different than what you have in long file names in windows.  Just like a file system.  If you only keep one kind of file in the streams under a specific storage you wouldn't need to have an extension or some other identifier to tell you what it was.

For example:

WAVFolderName = "WAVs";

if you were putting in a WAV called hohoho.wav you could ...

WAVStreamName = "hohoho.wav";

or maybe ...

WAVStreamName = "Santa Claus";


BMPFolderName = "BMPs";

if you were putting in a BMP called warhol15.bmp you could ...

BMPStreamName = "warhol15.bmp";

or maybe ...

BMPStreamName = "Campbell Soup Can";


Again, a compound file is a file system within a single file. An anology is windows explorer - the left hand pane contains the storages and the right hand pane has the streams within those storages.

As for the C++ file I/O ...

You can use the functions I mentioned above without any problem.  However, if you want to use pure c++ you would have to get some help from one of the other experts as I don't do much file I/O work using pure c++.

At the MSDN site on microsoft ...

http://msdn.microsoft.com/library/

.... you might have to register but it is free

You can find Brockschmidt's book - Inside OLE

When the tree (TOC) comes up on the left click on the + next to Books then click on the + next to Inside OLE then click on the + next to Chapter 7 Structured Storage and Compound Files.

Do some reading.  There is sample code available that shows you how to use Compound Files.

Take a look!

















0
 

Author Comment

by:bidr
Comment Utility
Thanks
0
 
LVL 4

Expert Comment

by:wylliker
Comment Utility
If you need any more help with this, you can keep posting back as a comment or open a new question.

If I had more time I could have gotten more involved with this - and given you more useful ready to use code.

(Have a system going to production the end of this week - and it seems as though the system is coming un-glued!)

You probably just have to get this task done, but long ago (1993 or so) when I first had worked with Structured Storage I really liked the concept - there were (are) just so many opportunities with the design of it.

Oh well, best of luck with your efforts!
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now