home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////
- //
- // DLL functions to get summary info from OLE 2.0 document files.
- //
- // Copyright ⌐ 1994 Somar Software, All Rights Reserved
- // Send problem reports and comments to 72202.2574@compuserve.com
- //
- // See cppsum.h for further documentation and change log.
- //
-
- #define STRICT
- #include <windows.h>
- #include <memory.h>
- #include <ole2ver.h>
- #include <storage.h>
- #include <compobj.h>
- #include "cppsum.h"
-
- // a temporary function was unreferenced and then removed by optimization
- // causing warning 4505
- #pragma warning(disable:4505)
-
- ///////////////////////////////////////////////////////////////////////////
- #define VT_I4 3
- #define VT_LPSTR 30
- #define VT_FILETIME 64
-
- typedef struct _PROPVALUE {
- DWORD vtType;
- union {
- FILETIME vtTime;
- LONG vtLong;
- struct {
- DWORD cBytes;
- char ch[1];
- } vtBSTR;
- } vtValue;
- } PROPVALUE;
- typedef PROPVALUE FAR * LPPROPVALUE;
-
- typedef struct _SUMMARYINFO {
- DWORD cBytes;
- DWORD cProps;
- struct {
- DWORD propID;
- DWORD dwOffset;
- } aProps[1];
- } SUMMARYINFO;
- typedef SUMMARYINFO FAR * LPSUMINFO;
-
- LPPROPVALUE FindProperty(HANDLE hSumInfo, DWORD pid);
-
- ///////////////////////////////////////////////////////////////////////////
- extern "C" WORD FAR PASCAL __export SumInfoInit()
- {
- DWORD dwVer = CoBuildVersion();
- if (rmm != HIWORD(dwVer)) return 0;
-
- HRESULT hr = CoInitialize(NULL);
- SCODE scode = GetScode(hr);
- if (scode == S_OK) return 1;
- if (scode == S_FALSE) return 2;
- return 0;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- extern "C" void FAR PASCAL __export SumInfoUninit(WORD wInitStatus)
- {
- if (wInitStatus == 1)
- CoUninitialize();
- }
-
- ///////////////////////////////////////////////////////////////////////////
- extern "C" HANDLE FAR PASCAL __export SumInfoOpenFile(LPSTR szPath)
- {
- BOOL bResult = FALSE;
- LPSUMINFO lpSumInfo;
- DWORD i;
- DWORD dwBytesInSection;
- HRESULT hr;
- ULONG ulBytesRead;
- LARGE_INTEGER li;
- LPSTREAM pIStream;
- LPSTORAGE pIStorage;
- HGLOBAL hglb = NULL;
-
- struct {
- WORD byteOrder;
- WORD wFormat;
- WORD osVersion1;
- WORD osVersion2;
- CLSID classId;
- DWORD cSections;
- } PropHeader;
- struct {
- DWORD dwords[4];
- DWORD dwOffset;
- } FIDAndOffset;
-
- hr = StgOpenStorage(szPath, NULL,
- STGM_READ | STGM_SHARE_DENY_NONE | STGM_PRIORITY,
- NULL, 0, &pIStorage);
- if (FAILED(hr)) return NULL;
-
- hr = pIStorage->OpenStream("\005SummaryInformation", NULL,
- STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
- if (FAILED(hr)) goto ReleaseStorage;
-
- LISet32(li, 0);
- hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
- if (hr != NOERROR) goto ReleaseStream;
-
- hr = pIStream->Read(&PropHeader, 28, &ulBytesRead);
- if (hr != NOERROR || ulBytesRead != 28) goto ReleaseStream;
-
- if (PropHeader.byteOrder != 0xFFFE) goto ReleaseStream;
- if (PropHeader.wFormat != 0) goto ReleaseStream;
-
- for (i = 0; i < PropHeader.cSections; i++) {
- hr = pIStream->Read(&FIDAndOffset, 20, &ulBytesRead);
- if (hr != NOERROR || ulBytesRead != 20) goto ReleaseStream;
- if (FIDAndOffset.dwords[0] == 0XF29F85E0 &&
- FIDAndOffset.dwords[1] == 0X10684FF9 &&
- FIDAndOffset.dwords[2] == 0X000891AB &&
- FIDAndOffset.dwords[3] == 0XD9B3272B) break;
- }
- if (i >= PropHeader.cSections) goto ReleaseStream;
-
- LISet32(li, FIDAndOffset.dwOffset);
- hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
- if (hr != NOERROR) goto ReleaseStream;
-
- hr = pIStream->Read(&dwBytesInSection, 4, &ulBytesRead);
- if (hr != NOERROR || ulBytesRead != 4) goto ReleaseStream;
-
- hglb = GlobalAlloc(GPTR, dwBytesInSection);
- if (hglb == NULL) goto ReleaseStream;
- lpSumInfo = (LPSUMINFO) GlobalLock(hglb);
- if (lpSumInfo == NULL) goto Free;
-
- hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
- if (hr != NOERROR) goto Unlock;
-
- hr = pIStream->Read(lpSumInfo, dwBytesInSection, &ulBytesRead);
- if (hr != NOERROR || ulBytesRead > dwBytesInSection) goto Unlock;
- // tbd: dwBytesInSection is long by 4 bytes for some Excel 5.0 files, so just
- // check that ulBytesRead is <= dwBytesInSection and not that they are equal
-
- GlobalUnlock(hglb);
-
- goto ReleaseStream;
-
- Unlock:
- GlobalUnlock(hglb);
-
- Free:
- GlobalFree(hglb);
- hglb = NULL;
-
- ReleaseStream:
- pIStream->Release();
-
- ReleaseStorage:
- pIStorage->Release();
-
- return hglb;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- extern "C" void FAR PASCAL __export SumInfoCloseFile(HANDLE hSumInfo)
- {
- GlobalFree(hSumInfo);
- }
-
- ///////////////////////////////////////////////////////////////////////////
- extern "C" BOOL FAR PASCAL __export SumInfoGetString(HANDLE hSumInfo,
- DWORD pid,
- LPSTR lpStr,
- int cbStr)
- {
- LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
- if (lpProp == NULL) return FALSE;
- if (lpProp->vtType != VT_LPSTR) return FALSE;
- int len = (int) lpProp->vtValue.vtBSTR.cBytes;
- if (len > cbStr) len = cbStr;
- if (len <= 0) {
- *(lpStr) = '\0';
- }
- else {
- lstrcpyn(lpStr, lpProp->vtValue.vtBSTR.ch, len);
- *(lpStr + len - 1) = '\0'; // len includes terminating null
- }
- return TRUE;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- extern "C" BOOL FAR PASCAL __export SumInfoGetLong(HANDLE hSumInfo,
- DWORD pid,
- LPLONG lpLong)
- {
- LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
- if (lpProp == NULL) return FALSE;
- if (lpProp->vtType != VT_I4) return FALSE;
- *lpLong = lpProp->vtValue.vtLong;
- return TRUE;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- extern "C" BOOL FAR PASCAL __export SumInfoGetTime(HANDLE hSumInfo,
- DWORD pid,
- LPWORD yr,
- LPWORD mon,
- LPWORD day,
- LPWORD hr,
- LPWORD min,
- LPWORD sec)
- {
- struct {
- unsigned int day : 5;
- unsigned int mon : 4;
- unsigned int yr : 7;
- } DosDate;
- struct {
- unsigned int sec2 : 5;
- unsigned int min : 6;
- unsigned int hr : 5;
- } DosTime;
-
- LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
- if (lpProp == NULL) return FALSE;
- if (lpProp->vtType != VT_FILETIME) return FALSE;
- if (!CoFileTimeToDosDateTime(&lpProp->vtValue.vtTime,
- (LPWORD) &DosDate, (LPWORD) &DosTime))
- return FALSE;
- *yr = (WORD) DosDate.yr + 1980;
- *mon = (WORD) DosDate.mon;
- *day = (WORD) DosDate.day;
- *hr = (WORD) DosTime.hr;
- *min = (WORD) DosTime.min;
- *sec = (WORD) DosTime.sec2 * 2;
- return TRUE;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- LPPROPVALUE FindProperty(HANDLE hSumInfo, DWORD pid)
- {
- LPPROPVALUE lpProp;
- DWORD i;
- LPSUMINFO lpSumInfo = (LPSUMINFO) GlobalLock(hSumInfo);
- if (lpSumInfo == NULL) return FALSE;
- for (i = 0; i < lpSumInfo->cProps; i++) {
- if (lpSumInfo->aProps[i].propID == pid) {
- lpProp = (LPPROPVALUE) ((LPBYTE) lpSumInfo +
- lpSumInfo->aProps[i].dwOffset);
- GlobalUnlock(hSumInfo);
- return lpProp;
- }
- }
- GlobalUnlock(hSumInfo);
- return NULL;
- }
-