Re: FOLLOWUP: RE: [JAWIN] IStorage

"Mcnamara, Sean D" <[email protected]> Mon, 5 Jun 2006 15:37:04 -0400
Newsgroups gmane.comp.windows.devel.jawin
Message-ID <57F935D6BB6B2543AF5D835DCE7CAF27020F9A9C@MD61EX100.ad.honeywell-tsi.com>
Andre,

A pointer to a pointer IStorage** is just an int. On a 32-bit platform,
a 4-byte (4*8=32 bit) memory address represents the location of each
space in memory. If you plan on calling this DLL in Windows 64-bit then
use a Java long data type, or just use a long anyway to be safe (should
work on 32-bit also.) When using pointers to and from a Windows DLL, the
integer representing the pointer *is* your "object reference". The
IStorage** pointer can eventually be used to call member functions of
the IStorage object it points to. To get the whole picture *easily*, you
need to use C++.

If you want to avoid C++, the following COM wrapper around the
Structured Storage API may be helpful:

http://www.codeproject.com/atl/structuredstorage.asp

This COM wrapper will be *much* easier to use from Jawin.

Before you deploy this, however, be aware of the additional overhead
incurred with your application:
*You will have one more file (a .DLL) to keep with your application, in
the bin directory with your .jar file.
*With this class, your control over the structured storage will be
somewhat less precise. 
*If you deploy into restricted environments such as a CITRIX server, you
may not be able to use RegSvr32 (the api DllRegisterServer) to register
this COM library. Failure to register a COM DLL is almost always bad
news for any application hoping to call the library.

At this intersection, you have several choices to proceed:

1. If you can't use COM in your environment and you have a Visual C++
compiler, use it! Write your code in C++ first and, once you get a
working C++ test case, the Jawin usage will become much clearer to you.

2. If you can use COM in your environment and you have a Visual C++
compiler, compile the source code linked to above, into a Windows DLL.
Then use Jawin Type Browser to generate Java wrappers.

3. If you can use COM in your environment and you don't have a Visual
C++ compiler, let me know and I will try and compile the sample DLL and
email it to you. It uses ATL so I'll see about static linking, and will
try and provide two versions (one with debugging symbols, and one
without) for convenience. 

4. If you can't use COM in your environment and you don't have a Visual
C++ compiler, you're doing pretty badly, here! :-) In this case you
should probably look into alternative libraries, or buying a Visual C++
compiler so you can learn how to interact with these APIs.

Good luck,
Sean



-----Original Message-----
From: Discussion of Java/Win32/COM integration with Jawin
[mailto:[email protected]] On Behalf Of Andre R. Santos
Sent: Monday, June 05, 2006 2:37 PM
To: [email protected]
Subject: Re: [JAWIN] FOLLOWUP: RE: [JAWIN] IStorage

I'm using the techniques described at
http://jawinproject.sourceforge.net/jawin.html#callingDll and I'm
getting an
error. This is what I've done so far:

Using Depency Walker, I found out that the function I want to call is
StgOpenStorage. This is the method signature:

WINOLEAPI StgOpenStorage(
  const WCHAR* pwcsName,
  IStorage* pstgPriority,
  DWORD grfMode,
  SNB snbExclude,
  DWORD reserved,
  IStorage** ppstgOpen
);

"IStorage** ppstg: [out] When the operation is successful, pointer to
the
location of an IStorage pointer to the opened storage object. This
parameter
is set to NULL if an error occurs."

What should I pass as a ppstgOpen parameter, and how I can use it later
to
open an IStream Object?

Here's the code, which works fine, I just don't know what do to next:

            functionOpenStorage= new FuncPtr("ole32.dll",
"StgOpenStorage");
            NakedByteStream nbs = new NakedByteStream();
            LittleEndianOutputStream leos = new
LittleEndianOutputStream(nbs);

            leos.writeStringUnicode("D:\\Filename.QGD");
            leos.writeInt(0);
            leos.writeInt(0);
            leos.writeInt(0);
            leos.writeInt(0);

//what parameter should I pass here? (using 0 to test)
            leos.writeInt(0);

             functionOpenStorage.invoke("GIIIII::", 24, nbs, null,
ReturnFlags.CHECK_NONE);