FileAlreadyExists, on Read Operation, via StgOpenStorage

Hello, first off I hope I'm delivering the topic properly.

In short I'm having problems using a function that I think is from the Windows layer, called StgOpenStorage1. I'm trying to use it to read a file but it's giving me an error. Upon investigating the value of the HRESULT2 it turns out to be a FileAlreadyExists2 error, which confuses me since I thought this is a read operation.

I'll append only the code relevant to the problem, about 10-15 lines. There's also some reference links in the bottom that might be of your interest.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int _tmain()
{
   iretVal = XLVersionFromFile("C:\\JACK.xlsx");
}

int XLVersionFromFile(char *filename)
{
   WCHAR wcFilename[1024];
   int i = mbstowcs(wcFilename, filename, strlen(filename));
   wcFilename[i] = 0;

   IStorage *pStorage;
   HRESULT hr;

   hr = ::StgOpenStorage(wcFilename, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);
   printf("\n\nError number 0x%x\n", hr);
}

Output:
 
Error number 0x80030050

References:
[1] http://msdn.microsoft.com/en-us/library/windows/desktop/aa380341%28v=vs.85%29.aspx
[2] http://msdn.microsoft.com/en-us/library/cc704587.aspx
[Original Example] http://support.microsoft.com/kb/178605
[Current Code] http://codepad.org/TPbelTk5

Notes:
- I'm using VS2010, had to do some code tweaks for that.
- I should note that I know other languages, but not C++. My apologizes for trying to use something that I did not learn, but it was the only option for my problem, and it didn't sound feasible to go deep into the language whereas all what I needed from it was only one seemingly simple module.
The example says that it determines version of .xls files whereas you are trying to determine version of .xlsx file. These two formats are very different, and I think this is the reason why your code doesn't work.
As Null has already said, you're trying to open a zip file with a call which only know how to handle compound storage files.

(A xslx file is a set of XML files, plus a few other bit and pieces, all zipped up; you can extract the contents with a zip tool if you want to see what's there.)

As the text for the error STG_E_FILEALREADYEXISTS says:

Indicates that the file exists but is not a storage object.

From:
StgOpenStorage function
http://msdn.microsoft.com/en-us/library/windows/desktop/aa380341%28v=vs.85%29.aspx

Which is right here. It's not a storage object; it's a zip file.

Andy
Last edited on
Thank you for the clarification, it sucks that the problem was this simple and yet I wasn't able to notice it >.>

Marking solved, though I wouldn't mind to know of a similar tool with a bigger scope, if you happen to know about one.
I've never seen an user do such a perfect first post.
My greetings.
Also your C++ "skills" are pretty good, looking at the syntax, tabbing, indentation...
It really looks like you could easily enter the C++ world.

On the topic:
You should use zlib to de-compress the xlsx, and get the right file to work with.
Let me enhance:
XSLX files are ZIP files.
Rename one, and try to see if you are able to work with one of the internal files.
Rename one, see if you are able to work with one of the internal files.

There's no need to rename the file to .zip; the file can be opened (with the appropriate zip library) whatever its extension. (Unless you want to make the file click-able in Explorer, of course.)

And as the files are XML inside (as I already mentioned), they are eay to work with. Esp. as the schema is publically avaliable:

5 Appendix A: Full XML Schema
http://msdn.microsoft.com/en-us/library/dd979921%28v=office.12%29.aspx

From
[MS-XLSX]: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format
http://msdn.microsoft.com/en-us/library/dd922181%28v=office.12%29.aspx

But there are libraries available:

LibXL
http://www.libxl.com/
excel library for developers

libOPC
http://libopc.codeplex.com/
Immature ("We released version 0.0.2.") but worth keeping an eye on.

This article:

How to Read and Write .xlsx (Excel 2007) file - Part I
http://www.codeproject.com/Articles/208075/How-to-read-and-write-xlsx-Excel-2007-file-Part-I

Etc.

Andy
Last edited on
andywestken wrote:
Rename one, see if you are able to work with one of the internal files.

There's no need to rename the file to .zip; the file can be opened (with the appropriate zip library) whatever its extension. (Unless you want to make the file click-able in Explorer, of course.)[/quote]
That's what I meant, yes, even if I personally use the "Open With..." function.
Last edited on
PS on the subject of zip files, I answered a related question here:

Working with zip and similar files
http://www.cplusplus.com/forum/general/104349/#msg563948

It's the list of zip libraries that might be useful as a starting point?

Of course, if you've go this way, then you need to worry about XML parsing, too.

Andy
Last edited on
Topic archived. No new replies allowed.