mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
404 lines
11 KiB
404 lines
11 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
|
//
|
|
// File: OLEDUP.CPP
|
|
//
|
|
// Contents: Quick-n-dirty functions to replace OLE APIs
|
|
//
|
|
// Functions: HexStringToDword
|
|
// GUIDFromString
|
|
// QV_StringFromCLSID
|
|
// QV_CLSIDFromString
|
|
// CheckSignature
|
|
// QV_StgIsStorageFile
|
|
//
|
|
// History: dd-mmm-yy History Comment
|
|
// 12-Oct-94 davepl NT Port
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "qvstub.h"
|
|
#pragma hdrstop
|
|
|
|
#define InRange(id, idFirst, idLast) ((UINT)(id-idFirst) <= (UINT)(idLast-idFirst))
|
|
|
|
// format for string form of GUID is (leading identifier ????)
|
|
// ????{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}
|
|
|
|
#define GUIDSTR_MAX (1+ 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
|
|
#define NEED_OLEINITIALIZE
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: HexStringToDword
|
|
//
|
|
// Synopsis: Scans a string for up to 8 hex digits, returns the binary
|
|
// value.
|
|
//
|
|
//
|
|
// Arguments: [lplpsz] String to scan
|
|
// [lpValue] OUT value from hex-binary conversion
|
|
// [cDigits] Num of digits to scan into string
|
|
// [chDelim] Delimiter to search for at end of hex num
|
|
//
|
|
// Returns: TRUE if string converted and delimiter found
|
|
//
|
|
//
|
|
// History: dd-mmm-yy History Comment
|
|
// 12-Oct-94 davepl NT Port
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
static BOOL HexStringToDword(LPCTSTR * lplpsz, DWORD FAR * lpValue, int cDigits, TCHAR chDelim)
|
|
{
|
|
register int ich;
|
|
register LPCTSTR lpsz = *lplpsz;
|
|
DWORD Value = 0;
|
|
BOOL fRet = TRUE;
|
|
|
|
// BUGBUG Validity of this character math under unicode!
|
|
// REVIEW should assert that cDigits is < 8
|
|
|
|
for (ich = 0; ich < cDigits; ich++)
|
|
{
|
|
TCHAR ch = lpsz[ich];
|
|
if (InRange(ch, '0', '9'))
|
|
{
|
|
Value = (Value << 4) + ch - '0';
|
|
}
|
|
else if ( InRange( (ch |= ('a'-'A')), 'a', 'f') )
|
|
{
|
|
Value = (Value << 4) + ch - 'a' + 10;
|
|
}
|
|
else
|
|
return(FALSE);
|
|
}
|
|
|
|
if (chDelim)
|
|
{
|
|
fRet = (lpsz[ich++] == chDelim);
|
|
}
|
|
|
|
*lpValue = Value;
|
|
*lplpsz = lpsz+ich;
|
|
|
|
return fRet;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GUIDFromString
|
|
//
|
|
// Synopsis: Extracts a GUID from a string
|
|
//
|
|
// Arguments: [lpsz] String to extract from
|
|
// [pguid] GUID to return on
|
|
//
|
|
// Returns: TRUE on success, FALSE on error
|
|
//
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 12-Oct-94 Davepl NT Port
|
|
//
|
|
// Notes: Trashes GUID in error case
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
STDAPI_(BOOL) GUIDFromString(LPCTSTR lpsz, LPGUID pguid)
|
|
{
|
|
DWORD dw;
|
|
if (*lpsz++ != '{' /*}*/ )
|
|
return FALSE;
|
|
|
|
if (!HexStringToDword(&lpsz, &pguid->Data1, sizeof(DWORD)*2, '-'))
|
|
return FALSE;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(WORD)*2, '-'))
|
|
return FALSE;
|
|
|
|
pguid->Data2 = (WORD)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(WORD)*2, '-'))
|
|
return FALSE;
|
|
|
|
pguid->Data3 = (WORD)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, 0))
|
|
return FALSE;
|
|
|
|
pguid->Data4[0] = (BYTE)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, '-'))
|
|
return FALSE;
|
|
|
|
pguid->Data4[1] = (BYTE)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, 0))
|
|
return FALSE;
|
|
|
|
pguid->Data4[2] = (BYTE)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, 0))
|
|
return FALSE;
|
|
|
|
pguid->Data4[3] = (BYTE)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, 0))
|
|
return FALSE;
|
|
|
|
pguid->Data4[4] = (BYTE)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, 0))
|
|
return FALSE;
|
|
|
|
pguid->Data4[5] = (BYTE)dw;
|
|
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, 0))
|
|
return FALSE;
|
|
|
|
pguid->Data4[6] = (BYTE)dw;
|
|
if (!HexStringToDword(&lpsz, &dw, sizeof(BYTE)*2, /*(*/ '}'))
|
|
return FALSE;
|
|
|
|
pguid->Data4[7] = (BYTE)dw;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: QV_StringFromCLSID
|
|
//
|
|
// Synopsis: Converts a CLSID (ie: GUID) to string form
|
|
//
|
|
// Arguments: [rguid] The GUID to convert
|
|
// [lpsz] Output string
|
|
// [cbMax] Size of output string
|
|
//
|
|
// Returns: Length of string (fixed) on success
|
|
// 0 if buffer is not large enough
|
|
//
|
|
// History: dd-mmm-yy History Comment
|
|
// 12-Oct-94 Davepl NT Port
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
STDAPI_(int) QV_StringFromCLSID(REFGUID rguid, LPTSTR lpsz, int cbMax)
|
|
{
|
|
if (cbMax < GUIDSTR_MAX)
|
|
return 0;
|
|
|
|
wsprintf(lpsz, TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
|
|
rguid.Data1, rguid.Data2, rguid.Data3,
|
|
rguid.Data4[0], rguid.Data4[1],
|
|
rguid.Data4[2], rguid.Data4[3],
|
|
rguid.Data4[4], rguid.Data4[5],
|
|
rguid.Data4[6], rguid.Data4[7]);
|
|
|
|
Assert(lstrlen(lpsz) + 1 == GUIDSTR_MAX);
|
|
|
|
return GUIDSTR_MAX;
|
|
}
|
|
|
|
//
|
|
// translate string form of CLSID into binary form.
|
|
// does not support Ole1Class classes.
|
|
// errors: E_INVALIDARG, CO_E_CLASSSTRING, REGDB_E_WRITEREGDB
|
|
//
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: QV_CLSIDFromString
|
|
//
|
|
// Synopsis: Converts CLSID to string. Does NOT support full the
|
|
// full functionality of the OLE API. Does not handle
|
|
// OLE 1 ProgID hashing, etc.
|
|
//
|
|
// Arguments: [lpsz] Input string to convert
|
|
// [lpclsid] Output CLSID
|
|
//
|
|
// Returns: NOERROR on success, CO_E_CLASSSTRING on failure
|
|
//
|
|
// History: dd-mmm-yy History Comment
|
|
// davepl NT Port
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
STDAPI QV_CLSIDFromString(LPCTSTR lpsz, LPCLSID lpclsid)
|
|
{
|
|
if (lpsz == NULL)
|
|
{
|
|
*lpclsid = CLSID_NULL;
|
|
return NOERROR;
|
|
}
|
|
|
|
return GUIDFromString(lpsz,lpclsid)
|
|
? NOERROR : ResultFromScode(CO_E_CLASSSTRING);
|
|
}
|
|
|
|
|
|
// Hard-coded docfile signature
|
|
// BUGBUG Byte ordering
|
|
|
|
const BYTE SIGSTG[] = {0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1};
|
|
const BYTE CBSIGSTG = sizeof(SIGSTG);
|
|
|
|
// The first portion of a storage file
|
|
|
|
// BUGBUG structure padding
|
|
|
|
struct SStorageFile
|
|
{
|
|
BYTE abSig[CBSIGSTG]; // Signature
|
|
CLSID _clid; // Class Id
|
|
};
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: QV_StgIsStorageFile
|
|
//
|
|
// Synopsis: Determines whether or not a given file is a docfile
|
|
//
|
|
// Arguments: [pszFile] Filename to check
|
|
//
|
|
// Returns: S_OK if its a storage
|
|
// S_FALSE if its not
|
|
// E_FAIL if file could not be opened at all
|
|
//
|
|
// History: dd-mmm-yy History Comment
|
|
// 12-Oct-94 davepl NT Port
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
//
|
|
// Worker function to check the signature
|
|
//
|
|
|
|
SCODE CheckSignature(BYTE *pb)
|
|
{
|
|
SCODE sc;
|
|
|
|
// Check for ship Docfile signature first
|
|
|
|
if (memcmp(pb, SIGSTG, CBSIGSTG) == 0)
|
|
sc = S_OK;
|
|
else
|
|
sc = STG_E_INVALIDHEADER;
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDAPI QV_StgIsStorageFile(LPCTSTR pszFile)
|
|
{
|
|
HANDLE hf;
|
|
SCODE sc = E_FAIL;
|
|
|
|
// NOTE: Changed from OpenFile in Win95 -> NT Port in order to use UNICODE
|
|
// filenames
|
|
|
|
hf = CreateFile(pszFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
if (hf != INVALID_HANDLE_VALUE)
|
|
{
|
|
SStorageFile stgfile;
|
|
DWORD cb;
|
|
|
|
if (TRUE == ReadFile(hf, &stgfile, sizeof(stgfile), &cb, NULL) &&
|
|
sizeof(stgfile) == cb &&
|
|
SUCCEEDED(CheckSignature(stgfile.abSig)) )
|
|
{
|
|
sc = S_OK;
|
|
}
|
|
else
|
|
{
|
|
sc = S_FALSE;
|
|
}
|
|
CloseHandle(hf);
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
// NOTE: Not compiled, so not ported from here on
|
|
|
|
#if 0
|
|
HINSTANCE g_hinstOLE = NULL;
|
|
|
|
FARPROC QV_GetOleProcAddress(LPCSTR pszProc)
|
|
{
|
|
if (!g_hinstOLE) {
|
|
g_hinstOLE = LoadLibrary("OLE32.DLL");
|
|
#ifdef NEED_OLEINITIALIZE
|
|
if (g_hinstOLE)
|
|
{
|
|
typedef HRESULT (STDAPICALLTYPE *LPOLEINITIALIZE)(LPMALLOC);
|
|
LPOLEINITIALIZE pfnInit = (LPOLEINITIALIZE)GetProcAddress(g_hinstOLE, "OleInitialize");
|
|
if (pfnInit) {
|
|
DebugMsg(DM_TRACE, TEXT("qv TR - QV_GetOlePA: Calling real OleInitialize"));
|
|
pfnInit(NULL);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (g_hinstOLE) {
|
|
return GetProcAddress(g_hinstOLE, pszProc);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void QV_UnloadOLE()
|
|
{
|
|
if (g_hinstOLE)
|
|
{
|
|
#ifdef NEED_OLEINITIALIZE
|
|
typedef void (STDAPICALLTYPE *LPOLEUNINITIALIZE)(void);
|
|
LPOLEUNINITIALIZE pfnUnInit = (LPOLEUNINITIALIZE)GetProcAddress(g_hinstOLE, "OleUnInitialize");
|
|
if (pfnUnInit) {
|
|
DebugMsg(DM_TRACE, TEXT("qv TR - QV_UnloadOLE: Calling real OleUnInitialize"));
|
|
pfnUnInit();
|
|
}
|
|
#endif
|
|
FreeLibrary(g_hinstOLE);
|
|
g_hinstOLE = NULL;
|
|
}
|
|
}
|
|
|
|
STDAPI QV_GetClassFile (LPCSTR pszFile, CLSID FAR* pclsid)
|
|
{
|
|
HRESULT hres = QV_StgIsStorageFile(pszFile);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
typedef HRESULT (STDAPICALLTYPE *LPGETCLASSFILE)(LPCOLESTR, CLSID FAR*);
|
|
LPGETCLASSFILE pfnGetClassFile;
|
|
pfnGetClassFile = (LPGETCLASSFILE)QV_GetOleProcAddress("GetClassFile");
|
|
if (pfnGetClassFile) {
|
|
OLECHAR szw[MAX_PATH];
|
|
DebugMsg(DM_TRACE, TEXT("qv TR - QV_GetClassFile: Calling real GetClassFile"));
|
|
mbstowcs(szw, pszFile, sizeof(szw));
|
|
hres=pfnGetClassFile(szw, pclsid);
|
|
} else {
|
|
hres = ResultFromScode(E_OUTOFMEMORY);
|
|
}
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
#endif
|