Source code of Windows XP (NT5)
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.

589 lines
11 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: utils.c
  3. *
  4. * Purpose: Conatains all the utility routines
  5. *
  6. * Created: 1990
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Raor, Srinik (../../1990) Designed and coded
  12. * curts created portable version for WIN16/32
  13. *
  14. \***************************************************************************/
  15. #include <windows.h>
  16. #include "cmacs.h"
  17. #include <shellapi.h>
  18. #include "ole.h"
  19. #include "dde.h"
  20. #include "srvr.h"
  21. #define KB_64 65536
  22. extern ATOM aTrue;
  23. extern ATOM aFalse;
  24. #ifdef WIN16
  25. extern BOOL bWLO;
  26. extern BOOL bWin30;
  27. #endif
  28. extern ATOM aStdCreateFromTemplate;
  29. extern ATOM aStdCreate;
  30. extern ATOM aStdOpen;
  31. extern ATOM aStdEdit;
  32. extern ATOM aStdShowItem;
  33. extern ATOM aStdClose;
  34. extern ATOM aStdExit;
  35. extern ATOM aStdDoVerbItem;
  36. extern BOOL (FAR PASCAL *lpfnIsTask) (HANDLE);
  37. // MapToHexStr: Converts WORD to hex string.
  38. void INTERNAL MapToHexStr (
  39. LPSTR lpbuf,
  40. HANDLE hdata
  41. ){
  42. int i;
  43. char ch;
  44. *lpbuf++ = '@';
  45. for ( i = sizeof(HANDLE)*2 - 1; i >= 0; i--) {
  46. ch = (char) ((((DWORD_PTR)hdata) >> (i * 4)) & 0x0000000f);
  47. if(ch > '9')
  48. ch += 'A' - 10;
  49. else
  50. ch += '0';
  51. *lpbuf++ = ch;
  52. }
  53. *lpbuf++ = '\0';
  54. }
  55. void INTERNAL UtilMemCpy (
  56. LPSTR lpdst,
  57. LPCSTR lpsrc,
  58. DWORD dwCount
  59. ){
  60. UINT HUGE_T * hpdst;
  61. UINT HUGE_T * hpsrc;
  62. UINT FAR * lpwDst;
  63. UINT FAR * lpwSrc;
  64. DWORD words;
  65. DWORD bytes;
  66. bytes = dwCount % MAPVALUE(2,4);
  67. words = dwCount >> MAPVALUE(1,2); //* we compare DWORDS
  68. //* in the 32 bit version
  69. #ifdef WIN16
  70. if (dwCount <= KB_64) {
  71. lpwDst = (WORD FAR *) lpdst;
  72. lpwSrc = (WORD FAR *) lpsrc;
  73. while (words--)
  74. *lpwDst++ = *lpwSrc++;
  75. if (bytes)
  76. * (char FAR *) lpwDst = * (char FAR *) lpwSrc;
  77. }
  78. else
  79. #else
  80. UNREFERENCED_PARAMETER(lpwDst);
  81. UNREFERENCED_PARAMETER(lpwSrc);
  82. #endif
  83. {
  84. hpdst = (UINT HUGE_T *) lpdst;
  85. hpsrc = (UINT HUGE_T *) lpsrc;
  86. for(;words--;)
  87. *hpdst++ = *hpsrc++;
  88. lpdst = (LPSTR) hpdst;
  89. lpsrc = (LPSTR) hpsrc;
  90. for(;bytes--;)
  91. *lpdst++ = *lpsrc++;
  92. }
  93. }
  94. //DuplicateData: Duplicates a given Global data handle.
  95. HANDLE INTERNAL DuplicateData (
  96. HANDLE hdata
  97. ){
  98. LPSTR lpsrc = NULL;
  99. LPSTR lpdst = NULL;
  100. HANDLE hdup = NULL;
  101. DWORD size;
  102. BOOL err = TRUE;
  103. if(!(lpsrc = GlobalLock (hdata)))
  104. return NULL;
  105. DEBUG_OUT (lpsrc, 0)
  106. hdup = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, (size = (DWORD)GlobalSize(hdata)));
  107. if(!(lpdst = GlobalLock (hdup)))
  108. goto errRtn;;
  109. err = FALSE;
  110. UtilMemCpy (lpdst, lpsrc, size);
  111. errRtn:
  112. if(lpsrc)
  113. GlobalUnlock (hdata);
  114. if(lpdst)
  115. GlobalUnlock (hdup);
  116. if (err && hdup)
  117. GlobalFree (hdup);
  118. return hdup;
  119. }
  120. //ScanBoolArg: scans the argument which is not included in
  121. //the quotes. These args could be only TRUE or FALSE for
  122. //the time being. !!!The scanning routines should be
  123. //merged and it should be generalized.
  124. LPSTR INTERNAL ScanBoolArg (
  125. LPSTR lpstr,
  126. BOOL FAR *lpflag
  127. ){
  128. LPSTR lpbool;
  129. ATOM aShow;
  130. char ch;
  131. lpbool = lpstr;
  132. // !!! These routines does not take care of quoted quotes.
  133. while((ch = *lpstr) && (!(ch == ')' || ch == ',')))
  134. lpstr++;
  135. if (ch == '\0')
  136. return NULL;
  137. *lpstr++ = '\0'; // terminate the arg by null
  138. // if terminated by paren, then check for end of command
  139. // syntax.
  140. // Check for the end of the command string.
  141. if (ch == ')') {
  142. if (*lpstr++ != ']')
  143. return NULL;
  144. if (*lpstr != '\0')
  145. return NULL; //finally should be terminated by null.
  146. }
  147. aShow = GlobalFindAtom (lpbool);
  148. if (aShow == aTrue)
  149. *lpflag = TRUE;
  150. else {
  151. if (aShow ==aFalse)
  152. *lpflag = FALSE;
  153. else
  154. return NULL;;
  155. }
  156. return lpstr;
  157. }
  158. //ScannumArg: Checks for the syntax of num arg in Execute and if
  159. //the arg is syntactically correct, returns the ptr to the
  160. //beginning of the next arg and also, returns the number
  161. //Does not take care of the last num arg in the list.
  162. LPSTR INTERNAL ScanNumArg (
  163. LPSTR lpstr,
  164. LPINT lpnum
  165. ){
  166. WORD val = 0;
  167. char ch;
  168. while((ch = *lpstr++) && (ch != ',')) {
  169. if (ch < '0' || ch >'9')
  170. return NULL;
  171. val += val * 10 + (ch - '0');
  172. }
  173. if(!ch)
  174. return NULL;
  175. *lpnum = val;
  176. return lpstr;
  177. }
  178. //ScanArg: Checks for the syntax of arg in Execute and if
  179. //the arg is syntactically correct, returns the ptr to the
  180. //beginning of the next arg or to the end of the excute string.
  181. LPSTR INTERNAL ScanArg (
  182. LPSTR lpstr
  183. ){
  184. // !!! These routines does not take care of quoted quotes.
  185. // first char should be quote.
  186. if (*(lpstr-1) != '\"')
  187. return NULL;
  188. while(*lpstr && *lpstr != '\"')
  189. lpstr++;
  190. if(*lpstr == '\0')
  191. return NULL;
  192. *lpstr++ = '\0'; // terminate the arg by null
  193. if(!(*lpstr == ',' || *lpstr == ')'))
  194. return NULL;
  195. if(*lpstr++ == ','){
  196. if(*lpstr == '\"')
  197. return ++lpstr;
  198. // If it is not quote, leave the ptr on the first char
  199. return lpstr;
  200. }
  201. // terminated by paren
  202. // already skiped right paren
  203. // Check for the end of the command string.
  204. if (*lpstr++ != ']')
  205. return NULL;
  206. if(*lpstr != '\0')
  207. return NULL; //finally should be terminated by null.
  208. return lpstr;
  209. }
  210. // ScanCommand: scanns the command string for the syntax
  211. // correctness. If syntactically correct, returns the ptr
  212. // to the first arg or to the end of the string.
  213. WORD INTERNAL ScanCommand (
  214. LPSTR lpstr,
  215. UINT wType,
  216. LPSTR FAR * lplpnextcmd,
  217. ATOM FAR * lpAtom
  218. ){
  219. // !!! These routines does not take care of quoted quotes.
  220. // and not taking care of blanks arround the operators
  221. // !!! We are not allowing blanks after operators.
  222. // Should be allright! since this is arestricted syntax.
  223. char ch;
  224. LPSTR lptemp = lpstr;
  225. while(*lpstr && (!(*lpstr == '(' || *lpstr == ']')))
  226. lpstr++;
  227. if(*lpstr == '\0')
  228. return 0;
  229. ch = *lpstr;
  230. *lpstr++ = '\0'; // set the end of command
  231. *lpAtom = GlobalFindAtom (lptemp);
  232. if (!IsOleCommand (*lpAtom, wType))
  233. return NON_OLE_COMMAND;
  234. if (ch == '(') {
  235. ch = *lpstr++;
  236. if (ch == ')') {
  237. if (*lpstr++ != ']')
  238. return 0;
  239. }
  240. else {
  241. if (ch != '\"')
  242. return 0;
  243. }
  244. *lplpnextcmd = lpstr;
  245. return OLE_COMMAND;
  246. }
  247. // terminated by ']'
  248. if (*(*lplpnextcmd = lpstr)) // if no nul termination, then it is error.
  249. return 0;
  250. return OLE_COMMAND;
  251. }
  252. //MakeDataAtom: Creates a data atom from the item string
  253. //and the item data otions.
  254. ATOM INTERNAL MakeDataAtom (
  255. ATOM aItem,
  256. int options
  257. ){
  258. char buf[MAX_STR];
  259. if (options == OLE_CHANGED)
  260. return DuplicateAtom (aItem);
  261. if (!aItem)
  262. buf[0] = '\0';
  263. else
  264. GlobalGetAtomName (aItem, (LPSTR)buf, MAX_STR);
  265. if (options == OLE_CLOSED)
  266. lstrcat ((LPSTR)buf, (LPSTR) "/Close");
  267. else {
  268. if (options == OLE_SAVED)
  269. lstrcat ((LPSTR)buf, (LPSTR) "/Save");
  270. }
  271. if (buf[0])
  272. return GlobalAddAtom ((LPSTR)buf);
  273. else
  274. return (ATOM)0;
  275. }
  276. //DuplicateAtom: Duplicates an atom
  277. ATOM INTERNAL DuplicateAtom (
  278. ATOM atom
  279. ){
  280. char buf[MAX_STR];
  281. Puts ("DuplicateAtom");
  282. if (!atom)
  283. return (ATOM)0;
  284. GlobalGetAtomName (atom, buf, MAX_STR);
  285. return GlobalAddAtom (buf);
  286. }
  287. // MakeGlobal: makes global out of strings.
  288. // works only for << 64k
  289. HANDLE INTERNAL MakeGlobal (
  290. LPCSTR lpstr
  291. ){
  292. int len = 0;
  293. HANDLE hdata = NULL;
  294. LPSTR lpdata = NULL;
  295. len = lstrlen (lpstr) + 1;
  296. hdata = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, len);
  297. if (hdata == NULL || (lpdata = (LPSTR) GlobalLock (hdata)) == NULL)
  298. goto errRtn;
  299. UtilMemCpy (lpdata, lpstr, (DWORD)len);
  300. GlobalUnlock (hdata);
  301. return hdata;
  302. errRtn:
  303. if (lpdata)
  304. GlobalUnlock (hdata);
  305. if (hdata)
  306. GlobalFree (hdata);
  307. return NULL;
  308. }
  309. BOOL INTERNAL CheckServer (
  310. LPSRVR lpsrvr
  311. ){
  312. if (!CheckPointer(lpsrvr, WRITE_ACCESS))
  313. return FALSE;
  314. if ((lpsrvr->sig[0] == 'S') && (lpsrvr->sig[1] == 'R'))
  315. return TRUE;
  316. return FALSE;
  317. }
  318. BOOL INTERNAL CheckServerDoc (
  319. LPDOC lpdoc
  320. ){
  321. if (!CheckPointer(lpdoc, WRITE_ACCESS))
  322. return FALSE;
  323. if ((lpdoc->sig[0] == 'S') && (lpdoc->sig[1] == 'D'))
  324. return TRUE;
  325. return FALSE;
  326. }
  327. BOOL INTERNAL PostMessageToClientWithBlock (
  328. HWND hWnd,
  329. UINT wMsg,
  330. WPARAM wParam,
  331. LPARAM lParam
  332. ){
  333. if (!IsWindowValid (hWnd)){
  334. ASSERT(FALSE, "Client's window is missing");
  335. return FALSE;
  336. }
  337. if (IsBlockQueueEmpty ((HWND)wParam) && PostMessage (hWnd, wMsg, wParam, lParam))
  338. return TRUE;
  339. BlockPostMsg (hWnd, wMsg, wParam, lParam);
  340. return TRUE;
  341. }
  342. BOOL INTERNAL PostMessageToClient (
  343. HWND hWnd,
  344. UINT wMsg,
  345. WPARAM wParam,
  346. LPARAM lParam
  347. ){
  348. if (!IsWindowValid (hWnd)){
  349. ASSERT(FALSE, "Client's window is missing");
  350. return FALSE;
  351. }
  352. if (IsBlockQueueEmpty ((HWND)wParam) && PostMessage (hWnd, wMsg, wParam, lParam))
  353. return TRUE;
  354. BlockPostMsg (hWnd, wMsg, wParam, lParam);
  355. return TRUE;
  356. }
  357. BOOL INTERNAL IsWindowValid (
  358. HWND hwnd
  359. ){
  360. #define TASK_OFFSET 0x00FA
  361. LPSTR lptask;
  362. HANDLE htask;
  363. if (!IsWindow (hwnd))
  364. return FALSE;
  365. #ifdef WIN32
  366. UNREFERENCED_PARAMETER(lptask);
  367. UNREFERENCED_PARAMETER(htask);
  368. return TRUE;//HACK
  369. #endif
  370. #ifdef WIN16
  371. if (bWLO)
  372. return TRUE;
  373. // now get the task handle and find out it is valid.
  374. htask = GetWindowTask (hwnd);
  375. if (bWin30 || !lpfnIsTask) {
  376. lptask = (LPSTR)(MAKELONG (TASK_OFFSET, htask));
  377. if (!CheckPointer(lptask, READ_ACCESS))
  378. return FALSE;
  379. // now check for the signature bytes of task block in kernel
  380. if (*lptask++ == 'T' && *lptask == 'D')
  381. return TRUE;
  382. }
  383. else {
  384. // From win31 onwards the API IsTask() can be used for task validation
  385. if ((*lpfnIsTask)(htask))
  386. return TRUE;
  387. }
  388. #endif
  389. return FALSE;
  390. }
  391. BOOL INTERNAL UtilQueryProtocol (
  392. ATOM aClass,
  393. LPSTR lpprotocol
  394. ){
  395. HKEY hKey;
  396. char key[MAX_STR];
  397. char class[MAX_STR];
  398. if (!aClass)
  399. return FALSE;
  400. if (!GlobalGetAtomName (aClass, class, MAX_STR))
  401. return FALSE;
  402. lstrcpy (key, class);
  403. lstrcat (key, "\\protocol\\");
  404. lstrcat (key, lpprotocol);
  405. lstrcat (key, "\\server");
  406. if (RegOpenKey (HKEY_CLASSES_ROOT, key, &hKey))
  407. return FALSE;
  408. RegCloseKey (hKey);
  409. return TRUE;
  410. }
  411. BOOL INTERNAL IsOleCommand (
  412. ATOM aCmd,
  413. UINT wType
  414. ){
  415. if (wType == WT_SRVR) {
  416. if ((aCmd == aStdCreateFromTemplate)
  417. || (aCmd == aStdCreate)
  418. || (aCmd == aStdOpen)
  419. || (aCmd == aStdEdit)
  420. || (aCmd == aStdShowItem)
  421. || (aCmd == aStdClose)
  422. || (aCmd == aStdExit))
  423. return TRUE;
  424. }
  425. else {
  426. if ((aCmd == aStdClose)
  427. || (aCmd == aStdDoVerbItem)
  428. || (aCmd == aStdShowItem))
  429. return TRUE;
  430. }
  431. return FALSE;
  432. }