windows-nt/Source/XPSP1/NT/com/winole/server/utils.c
2020-09-26 16:20:57 +08:00

590 lines
11 KiB
C

/****************************** 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
* curts created portable version for WIN16/32
*
\***************************************************************************/
#include <windows.h>
#include "cmacs.h"
#include <shellapi.h>
#include "ole.h"
#include "dde.h"
#include "srvr.h"
#define KB_64 65536
extern ATOM aTrue;
extern ATOM aFalse;
#ifdef WIN16
extern BOOL bWLO;
extern BOOL bWin30;
#endif
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 (
LPSTR lpbuf,
HANDLE hdata
){
int i;
char ch;
*lpbuf++ = '@';
for ( i = sizeof(HANDLE)*2 - 1; i >= 0; i--) {
ch = (char) ((((DWORD_PTR)hdata) >> (i * 4)) & 0x0000000f);
if(ch > '9')
ch += 'A' - 10;
else
ch += '0';
*lpbuf++ = ch;
}
*lpbuf++ = '\0';
}
void INTERNAL UtilMemCpy (
LPSTR lpdst,
LPCSTR lpsrc,
DWORD dwCount
){
UINT HUGE_T * hpdst;
UINT HUGE_T * hpsrc;
UINT FAR * lpwDst;
UINT FAR * lpwSrc;
DWORD words;
DWORD bytes;
bytes = dwCount % MAPVALUE(2,4);
words = dwCount >> MAPVALUE(1,2); //* we compare DWORDS
//* in the 32 bit version
#ifdef WIN16
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
#else
UNREFERENCED_PARAMETER(lpwDst);
UNREFERENCED_PARAMETER(lpwSrc);
#endif
{
hpdst = (UINT HUGE_T *) lpdst;
hpsrc = (UINT HUGE_T *) lpsrc;
for(;words--;)
*hpdst++ = *hpsrc++;
lpdst = (LPSTR) hpdst;
lpsrc = (LPSTR) hpsrc;
for(;bytes--;)
*lpdst++ = *lpsrc++;
}
}
//DuplicateData: Duplicates a given Global data handle.
HANDLE INTERNAL DuplicateData (
HANDLE hdata
){
LPSTR lpsrc = NULL;
LPSTR lpdst = NULL;
HANDLE hdup = NULL;
DWORD size;
BOOL err = TRUE;
if(!(lpsrc = GlobalLock (hdata)))
return NULL;
DEBUG_OUT (lpsrc, 0)
hdup = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, (size = (DWORD)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 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 == ',')))
lpstr++;
if (ch == '\0')
return NULL;
*lpstr++ = '\0'; // 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 != '\0')
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 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
){
// !!! These routines does not take care of quoted quotes.
// first char should be quote.
if (*(lpstr-1) != '\"')
return NULL;
while(*lpstr && *lpstr != '\"')
lpstr++;
if(*lpstr == '\0')
return NULL;
*lpstr++ = '\0'; // 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 != '\0')
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 lpstr,
UINT 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 == ']')))
lpstr++;
if(*lpstr == '\0')
return 0;
ch = *lpstr;
*lpstr++ = '\0'; // set the end of command
*lpAtom = GlobalFindAtom (lptemp);
if (!IsOleCommand (*lpAtom, wType))
return NON_OLE_COMMAND;
if (ch == '(') {
ch = *lpstr++;
if (ch == ')') {
if (*lpstr++ != ']')
return 0;
}
else {
if (ch != '\"')
return 0;
}
*lplpnextcmd = lpstr;
return OLE_COMMAND;
}
// terminated by ']'
if (*(*lplpnextcmd = lpstr)) // if no nul termination, then it is error.
return 0;
return OLE_COMMAND;
}
//MakeDataAtom: Creates a data atom from the item string
//and the item data otions.
ATOM INTERNAL MakeDataAtom (
ATOM aItem,
int options
){
char buf[MAX_STR];
if (options == OLE_CHANGED)
return DuplicateAtom (aItem);
if (!aItem)
buf[0] = '\0';
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 (ATOM)0;
}
//DuplicateAtom: Duplicates an atom
ATOM INTERNAL DuplicateAtom (
ATOM atom
){
char buf[MAX_STR];
Puts ("DuplicateAtom");
if (!atom)
return (ATOM)0;
GlobalGetAtomName (atom, buf, MAX_STR);
return GlobalAddAtom (buf);
}
// MakeGlobal: makes global out of strings.
// works only for << 64k
HANDLE INTERNAL MakeGlobal (
LPCSTR 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
){
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
){
if (!CheckPointer(lpdoc, WRITE_ACCESS))
return FALSE;
if ((lpdoc->sig[0] == 'S') && (lpdoc->sig[1] == 'D'))
return TRUE;
return FALSE;
}
BOOL INTERNAL PostMessageToClientWithBlock (
HWND hWnd,
UINT wMsg,
WPARAM wParam,
LPARAM 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 hWnd,
UINT wMsg,
WPARAM wParam,
LPARAM 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
){
#define TASK_OFFSET 0x00FA
LPSTR lptask;
HANDLE htask;
if (!IsWindow (hwnd))
return FALSE;
#ifdef WIN32
UNREFERENCED_PARAMETER(lptask);
UNREFERENCED_PARAMETER(htask);
return TRUE;//HACK
#endif
#ifdef WIN16
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;
}
#endif
return FALSE;
}
BOOL INTERNAL UtilQueryProtocol (
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 (
ATOM aCmd,
UINT 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;
}