windows-nt/Source/XPSP1/NT/base/mvdm/wow16/ole/server/utils.c
2020-09-26 16:20:57 +08:00

598 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************** Module Header ******************************\
* Module Name: utils.c
*
* Purpose: Conatains all the utility routines
*
* Created: 1990
*
* Copyright (c) 1990, 1991 Microsoft Corporation
*
* History:
* Raor, Srinik (../../1990) Designed and coded
*
\***************************************************************************/
#include <windows.h>
#include "cmacs.h"
#include <shellapi.h>
#include "ole.h"
#include "dde.h"
#include "srvr.h"
#ifndef HUGE
#define HUGE huge
#endif
#define KB_64 65536
extern ATOM aTrue;
extern ATOM aFalse;
extern BOOL bWLO;
extern BOOL bWin30;
extern ATOM aStdCreateFromTemplate;
extern ATOM aStdCreate;
extern ATOM aStdOpen;
extern ATOM aStdEdit;
extern ATOM aStdShowItem;
extern ATOM aStdClose;
extern ATOM aStdExit;
extern ATOM aStdDoVerbItem;
extern BOOL (FAR PASCAL *lpfnIsTask) (HANDLE);
// MapToHexStr: Converts WORD to hex string.
void INTERNAL MapToHexStr (lpbuf, hdata)
LPSTR lpbuf;
HANDLE hdata;
{
int i;
char ch;
*lpbuf++ = '@';
for ( i = 3; i >= 0; i--) {
ch = (char) ((((WORD)hdata) >> (i * 4)) & 0x000f);
if(ch > '9')
ch += 'A' - 10;
else
ch += '0';
*lpbuf++ = ch;
}
*lpbuf++ = NULL;
}
void INTERNAL UtilMemCpy (lpdst, lpsrc, dwCount)
LPSTR lpdst;
LPSTR lpsrc;
DWORD dwCount;
{
WORD HUGE * hpdst;
WORD HUGE * hpsrc;
WORD FAR * lpwDst;
WORD FAR * lpwSrc;
DWORD words;
DWORD bytes;
bytes = dwCount % 2;
words = dwCount >> 1; //* we should compare DWORDS
//* in the 32 bit version
if (dwCount <= KB_64) {
lpwDst = (WORD FAR *) lpdst;
lpwSrc = (WORD FAR *) lpsrc;
while (words--)
*lpwDst++ = *lpwSrc++;
if (bytes)
* (char FAR *) lpwDst = * (char FAR *) lpwSrc;
}
else {
hpdst = (WORD HUGE *) lpdst;
hpsrc = (WORD HUGE *) lpsrc;
while (words--)
*hpdst++ = *hpsrc++;
if (bytes)
*(char HUGE *) hpdst = * (char HUGE *) hpsrc;
}
}
//DuplicateData: Duplicates a given Global data handle.
HANDLE INTERNAL DuplicateData (hdata)
HANDLE hdata;
{
LPSTR lpsrc = NULL;
LPSTR lpdst = NULL;
HANDLE hdup = NULL;
DWORD size;
BOOL err = TRUE;
if(!(lpsrc = GlobalLock (hdata)))
return NULL;
hdup = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, (size = GlobalSize(hdata)));
if(!(lpdst = GlobalLock (hdup)))
goto errRtn;;
err = FALSE;
UtilMemCpy (lpdst, lpsrc, size);
errRtn:
if(lpsrc)
GlobalUnlock (hdata);
if(lpdst)
GlobalUnlock (hdup);
if (err && hdup)
GlobalFree (hdup);
return hdup;
}
//ScanBoolArg: scans the argument which is not included in
//the quotes. These args could be only TRUE or FALSE for
//the time being. !!!The scanning routines should be
//merged and it should be generalized.
LPSTR INTERNAL ScanBoolArg (lpstr, lpflag)
LPSTR lpstr;
BOOL FAR *lpflag;
{
LPSTR lpbool;
ATOM aShow;
char ch;
lpbool = lpstr;
// !!! These routines does not take care of quoted quotes.
while((ch = *lpstr) && (!(ch == ')' || ch == ',')))
{ //[J1]
#if defined(FE_SB) //[J1]
lpstr = AnsiNext( lpstr ); //[J1]
#else //[J1]
lpstr++;
#endif //[J1]
} //[J1]
if(ch == NULL)
return NULL;
*lpstr++ = NULL; // terminate the arg by null
// if terminated by paren, then check for end of command
// syntax.
// Check for the end of the command string.
if (ch == ')') {
if (*lpstr++ != ']')
return NULL;
if(*lpstr != NULL)
return NULL; //finally should be terminated by null.
}
aShow = GlobalFindAtom (lpbool);
if (aShow == aTrue)
*lpflag = TRUE;
else {
if (aShow ==aFalse)
*lpflag = FALSE;
else
return NULL;;
}
return lpstr;
}
//ScannumArg: Checks for the syntax of num arg in Execute and if
//the arg is syntactically correct, returns the ptr to the
//beginning of the next arg and also, returns the number
//Does not take care of the last num arg in the list.
LPSTR INTERNAL ScanNumArg (lpstr, lpnum)
LPSTR lpstr;
LPINT lpnum;
{
WORD val = 0;
char ch;
while((ch = *lpstr++) && (ch != ',')) {
if (ch < '0' || ch >'9')
return NULL;
val += val * 10 + (ch - '0');
}
if(!ch)
return NULL;
*lpnum = val;
return lpstr;
}
//ScanArg: Checks for the syntax of arg in Execute and if
//the arg is syntactically correct, returns the ptr to the
//beginning of the next arg or to the end of the excute string.
LPSTR INTERNAL ScanArg (lpstr)
LPSTR lpstr;
{
// !!! These routines does not take care of quoted quotes.
// first char should be quote.
if (*(lpstr-1) != '\"')
return NULL;
while(*lpstr && *lpstr != '\"')
{ //[J1]
#if defined(FE_SB) //[J1]
lpstr = AnsiNext( lpstr ); //[J1]
#else //[J1]
lpstr++;
#endif //[J1]
} //[J1]
if(*lpstr == NULL)
return NULL;
*lpstr++ = NULL; // terminate the arg by null
if(!(*lpstr == ',' || *lpstr == ')'))
return NULL;
if(*lpstr++ == ','){
if(*lpstr == '\"')
return ++lpstr;
// If it is not quote, leave the ptr on the first char
return lpstr;
}
// terminated by paren
// already skiped right paren
// Check for the end of the command string.
if (*lpstr++ != ']')
return NULL;
if(*lpstr != NULL)
return NULL; //finally should be terminated by null.
return lpstr;
}
// ScanCommand: scanns the command string for the syntax
// correctness. If syntactically correct, returns the ptr
// to the first arg or to the end of the string.
WORD INTERNAL ScanCommand (lpstr, wType, lplpnextcmd, lpAtom)
LPSTR lpstr;
WORD wType;
LPSTR FAR * lplpnextcmd;
ATOM FAR * lpAtom;
{
// !!! These routines does not take care of quoted quotes.
// and not taking care of blanks arround the operators
// !!! We are not allowing blanks after operators.
// Should be allright! since this is arestricted syntax.
char ch;
LPSTR lptemp = lpstr;
while(*lpstr && (!(*lpstr == '(' || *lpstr == ']')))
{ //[J1]
#if defined(FE_SB) //[J1]
lpstr = AnsiNext( lpstr ); //[J1]
#else //[J1]
lpstr++;
#endif //[J1]
} //[J1]
if(*lpstr == NULL)
return NULL;
ch = *lpstr;
*lpstr++ = NULL; // set the end of command
*lpAtom = GlobalFindAtom (lptemp);
if (!IsOleCommand (*lpAtom, wType))
return NON_OLE_COMMAND;
if (ch == '(') {
#if defined(FE_SB) //[J1]
ch = *lpstr; //[J1]
lpstr = AnsiNext( lpstr ); //[J1]
#else //[J1]
ch = *lpstr++;
#endif //[J1]
if (ch == ')') {
if (*lpstr++ != ']')
return NULL;
}
else {
if (ch != '\"')
return NULL;
}
*lplpnextcmd = lpstr;
return OLE_COMMAND;
}
// terminated by ']'
if (*(*lplpnextcmd = lpstr)) // if no nul termination, then it is error.
return NULL;
return OLE_COMMAND;
}
//MakeDataAtom: Creates a data atom from the item string
//and the item data otions.
ATOM INTERNAL MakeDataAtom (aItem, options)
ATOM aItem;
int options;
{
char buf[MAX_STR];
if (options == OLE_CHANGED)
return DuplicateAtom (aItem);
if (!aItem)
buf[0] = NULL;
else
GlobalGetAtomName (aItem, (LPSTR)buf, MAX_STR);
if (options == OLE_CLOSED)
lstrcat ((LPSTR)buf, (LPSTR) "/Close");
else {
if (options == OLE_SAVED)
lstrcat ((LPSTR)buf, (LPSTR) "/Save");
}
if (buf[0])
return GlobalAddAtom ((LPSTR)buf);
else
return NULL;
}
//DuplicateAtom: Duplicates an atom
ATOM INTERNAL DuplicateAtom (atom)
ATOM atom;
{
char buf[MAX_STR];
Puts ("DuplicateAtom");
if (!atom)
return NULL;
GlobalGetAtomName (atom, buf, MAX_STR);
return GlobalAddAtom (buf);
}
// MakeGlobal: makes global out of strings.
// works only for << 64k
HANDLE INTERNAL MakeGlobal (lpstr)
LPSTR lpstr;
{
int len = 0;
HANDLE hdata = NULL;
LPSTR lpdata = NULL;
len = lstrlen (lpstr) + 1;
hdata = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, len);
if (hdata == NULL || (lpdata = (LPSTR) GlobalLock (hdata)) == NULL)
goto errRtn;
UtilMemCpy (lpdata, lpstr, (DWORD)len);
GlobalUnlock (hdata);
return hdata;
errRtn:
if (lpdata)
GlobalUnlock (hdata);
if (hdata)
GlobalFree (hdata);
return NULL;
}
BOOL INTERNAL CheckServer (lpsrvr)
LPSRVR lpsrvr;
{
if (!CheckPointer(lpsrvr, WRITE_ACCESS))
return FALSE;
if ((lpsrvr->sig[0] == 'S') && (lpsrvr->sig[1] == 'R'))
return TRUE;
return FALSE;
}
BOOL INTERNAL CheckServerDoc (lpdoc)
LPDOC lpdoc;
{
if (!CheckPointer(lpdoc, WRITE_ACCESS))
return FALSE;
if ((lpdoc->sig[0] == 'S') && (lpdoc->sig[1] == 'D'))
return TRUE;
return FALSE;
}
BOOL INTERNAL PostMessageToClientWithBlock (hWnd, wMsg, wParam, lParam)
HWND hWnd;
WORD wMsg;
WORD wParam;
DWORD lParam;
{
if (!IsWindowValid (hWnd)) {
ASSERT(FALSE, "Client's window is missing");
return FALSE;
}
if (IsBlockQueueEmpty ((HWND)wParam) && PostMessage (hWnd, wMsg, wParam, lParam))
return TRUE;
BlockPostMsg (hWnd, wMsg, wParam, lParam);
return TRUE;
}
BOOL INTERNAL PostMessageToClient (hWnd, wMsg, wParam, lParam)
HWND hWnd;
WORD wMsg;
WORD wParam;
DWORD lParam;
{
if (!IsWindowValid (hWnd)) {
ASSERT(FALSE, "Client's window is missing");
return FALSE;
}
if (IsBlockQueueEmpty ((HWND)wParam) && PostMessage (hWnd, wMsg, wParam, lParam))
return TRUE;
BlockPostMsg (hWnd, wMsg, wParam, lParam);
return TRUE;
}
BOOL INTERNAL IsWindowValid (hwnd)
HWND hwnd;
{
#define TASK_OFFSET 0x00FA
LPSTR lptask;
HANDLE htask;
if (!IsWindow (hwnd))
return FALSE;
if (bWLO)
return TRUE;
// now get the task handle and find out it is valid.
htask = GetWindowTask (hwnd);
if (bWin30 || !lpfnIsTask) {
lptask = (LPSTR)(MAKELONG (TASK_OFFSET, htask));
if (!CheckPointer(lptask, READ_ACCESS))
return FALSE;
// now check for the signature bytes of task block in kernel
if (*lptask++ == 'T' && *lptask == 'D')
return TRUE;
}
else {
// From win31 onwards the API IsTask() can be used for task validation
if ((*lpfnIsTask)(htask))
return TRUE;
}
return FALSE;
}
BOOL INTERNAL UtilQueryProtocol (aClass, lpprotocol)
ATOM aClass;
LPSTR lpprotocol;
{
HKEY hKey;
char key[MAX_STR];
char class[MAX_STR];
if (!aClass)
return FALSE;
if (!GlobalGetAtomName (aClass, class, MAX_STR))
return FALSE;
lstrcpy (key, class);
lstrcat (key, "\\protocol\\");
lstrcat (key, lpprotocol);
lstrcat (key, "\\server");
if (RegOpenKey (HKEY_CLASSES_ROOT, key, &hKey))
return FALSE;
RegCloseKey (hKey);
return TRUE;
}
BOOL INTERNAL IsOleCommand (aCmd, wType)
ATOM aCmd;
WORD wType;
{
if (wType == WT_SRVR) {
if ((aCmd == aStdCreateFromTemplate)
|| (aCmd == aStdCreate)
|| (aCmd == aStdOpen)
|| (aCmd == aStdEdit)
|| (aCmd == aStdShowItem)
|| (aCmd == aStdClose)
|| (aCmd == aStdExit))
return TRUE;
}
else {
if ((aCmd == aStdClose)
|| (aCmd == aStdDoVerbItem)
|| (aCmd == aStdShowItem))
return TRUE;
}
return FALSE;
}