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.

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