|
|
/****************************** 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; }
|