Leaked source code of windows server 2003
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.

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