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.

502 lines
12 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // garb.c - garbage bag functions
  24. ////
  25. #include "winlocal.h"
  26. #include "garb.h"
  27. #include "file.h"
  28. #include "list.h"
  29. #include "mem.h"
  30. #include "str.h"
  31. #include "trace.h"
  32. ////
  33. // private definitions
  34. ////
  35. // garb control struct
  36. //
  37. typedef struct GARB
  38. {
  39. DWORD dwVersion;
  40. HINSTANCE hInst;
  41. HTASK hTask;
  42. HLIST hList;
  43. } GARB, FAR *LPGARB;
  44. // garbage element struct
  45. //
  46. typedef struct GARBELEM
  47. {
  48. LPVOID elem;
  49. DWORD dwFlags;
  50. } GARBELEM, FAR *LPGARBELEM;
  51. // helper functions
  52. //
  53. static LPGARB GarbGetPtr(HGARB hGarb);
  54. static HGARB GarbGetHandle(LPGARB lpGarb);
  55. static LPGARBELEM GarbElemCreate(LPVOID elem, DWORD dwFlags);
  56. static int GarbElemDestroy(LPGARBELEM lpGarbElem);
  57. ////
  58. // public functions
  59. ////
  60. // GarbInit - initialize garbage bag
  61. // <dwVersion> (i) must be GARB_VERSION
  62. // <hInst> (i) instance handle of calling module
  63. // return handle (NULL if error)
  64. //
  65. HGARB DLLEXPORT WINAPI GarbInit(DWORD dwVersion, HINSTANCE hInst)
  66. {
  67. BOOL fSuccess = TRUE;
  68. LPGARB lpGarb = NULL;
  69. if (dwVersion != GARB_VERSION)
  70. fSuccess = TraceFALSE(NULL);
  71. else if (hInst == NULL)
  72. fSuccess = TraceFALSE(NULL);
  73. else if ((lpGarb = (LPGARB) MemAlloc(NULL, sizeof(GARB), 0)) == NULL)
  74. fSuccess = TraceFALSE(NULL);
  75. // create a list to hold garbage bag elements
  76. //
  77. else if ((lpGarb->hList = ListCreate(LIST_VERSION, hInst)) == NULL)
  78. fSuccess = TraceFALSE(NULL);
  79. else
  80. {
  81. lpGarb->dwVersion = dwVersion;
  82. lpGarb->hInst = hInst;
  83. lpGarb->hTask = GetCurrentTask();
  84. }
  85. if (!fSuccess)
  86. {
  87. GarbTerm(GarbGetHandle(lpGarb));
  88. lpGarb = NULL;
  89. }
  90. return fSuccess ? GarbGetHandle(lpGarb) : NULL;
  91. }
  92. // GarbTerm - dispose of each element in garbage bag, then destroy it
  93. // <hGarb> (i) handle returned from GarbInit
  94. // return 0 if success
  95. //
  96. // NOTE: elements are disposed of in the order they were placed
  97. // in the garbage bag; therefore, for instance, if a temporary
  98. // file is to be first closed and then deleted, call GarbAddElement()
  99. // first with the file handle (GARBELEM_HFILE) and then with the
  100. // file name (GARBELEM_TEMPFILENAME).
  101. //
  102. int DLLEXPORT WINAPI GarbTerm(HGARB hGarb)
  103. {
  104. BOOL fSuccess = TRUE;
  105. LPGARB lpGarb;
  106. if ((lpGarb = GarbGetPtr(hGarb)) == NULL)
  107. fSuccess = TraceFALSE(NULL);
  108. else if (lpGarb->hList != NULL)
  109. {
  110. // dispose of each element in the list
  111. //
  112. while (fSuccess && !ListIsEmpty(lpGarb->hList))
  113. {
  114. LPGARBELEM lpGarbElem;
  115. if ((lpGarbElem = ListRemoveHead(lpGarb->hList)) == NULL)
  116. fSuccess = TraceFALSE(NULL);
  117. else if (GarbElemDestroy(lpGarbElem) != 0)
  118. TraceFALSE(NULL); // keep going despite failure
  119. }
  120. // destroy the list
  121. //
  122. if (ListDestroy(lpGarb->hList) != 0)
  123. fSuccess = TraceFALSE(NULL);
  124. else
  125. lpGarb->hList = NULL;
  126. }
  127. if ((lpGarb = MemFree(NULL, lpGarb)) != NULL)
  128. fSuccess = TraceFALSE(NULL);
  129. return fSuccess ? 0 : -1;
  130. }
  131. // GarbAddElement - add an element to the garbage bag
  132. // <hGarb> (i) handle returned from GarbInit
  133. // <elem> (i) garbage elem
  134. // <dwFlags> (i) element flags (determines disposal method)
  135. // GARBELEM_TEMPFILENAME FileRemove(elem)
  136. // GARBELEM_STRDUP StrDupFree(elem)
  137. // GARBELEM_GLOBALPTR GlobalFreePtr(elem)
  138. // GARBELEM_LOCALPTR LocalFreePtr(elem)
  139. #ifdef _WIN32
  140. // GARBELEM_HEAPPTR HeapFreePtr(GetProcessHeap(), 0, elem)
  141. #endif
  142. // GARBELEM_CURSOR DestroyCursor(elem)
  143. // GARBELEM_ICON DestroyIcon(elem)
  144. // GARBELEM_MENU DestroyMenu(elem)
  145. // GARBELEM_WINDOW DestroyWindow(elem)
  146. // GARBELEM_DC DeleteDC(elem)
  147. // GARBELEM_METAFILE DeleteMetafile(elem)
  148. // GARBELEM_PEN DeleteObject(elem)
  149. // GARBELEM_BRUSH DeleteObject(elem)
  150. // GARBELEM_FONT DeleteObject(elem)
  151. // GARBELEM_BITMAP DeleteObject(elem)
  152. // GARBELEM_RGN DeleteObject(elem)
  153. // GARBELEM_PALETTE DeleteObject(elem)
  154. // GARBELEM_HFIL FileClose(elem)
  155. // GARBELEM_HFILE _lclose(elem)
  156. // return 0 if success
  157. //
  158. // NOTE: it is possible to combine flags, such as
  159. // (GARBELEM_TEMPFILENAME | GARBELEM_STRDUP)
  160. // In this case the FileRemove() will be called before StrDupFree()
  161. // Most flag combinations, however, make no sense.
  162. //
  163. int DLLEXPORT WINAPI GarbAddElement(HGARB hGarb, LPVOID elem, DWORD dwFlags)
  164. {
  165. BOOL fSuccess = TRUE;
  166. LPGARB lpGarb;
  167. LPGARBELEM lpGarbElem = NULL;
  168. if ((lpGarb = GarbGetPtr(hGarb)) == NULL)
  169. fSuccess = TraceFALSE(NULL);
  170. else if ((lpGarbElem = GarbElemCreate(elem, dwFlags)) == NULL)
  171. fSuccess = TraceFALSE(NULL);
  172. else if (ListAddTail(lpGarb->hList, lpGarbElem) == NULL)
  173. fSuccess = TraceFALSE(NULL);
  174. if (!fSuccess)
  175. {
  176. GarbElemDestroy(lpGarbElem);
  177. lpGarbElem = NULL;
  178. }
  179. return fSuccess ? 0 : -1;
  180. }
  181. ////
  182. // helper functions
  183. ////
  184. // GarbGetPtr - verify that garb handle is valid,
  185. // <hGarb> (i) handle returned from GarbInit
  186. // return corresponding garb pointer (NULL if error)
  187. //
  188. static LPGARB GarbGetPtr(HGARB hGarb)
  189. {
  190. BOOL fSuccess = TRUE;
  191. LPGARB lpGarb;
  192. if ((lpGarb = (LPGARB) hGarb) == NULL)
  193. fSuccess = TraceFALSE(NULL);
  194. else if (IsBadWritePtr(lpGarb, sizeof(GARB)))
  195. fSuccess = TraceFALSE(NULL);
  196. #ifdef CHECKTASK
  197. // make sure current task owns the garb handle
  198. //
  199. else if (lpGarb->hTask != GetCurrentTask())
  200. fSuccess = TraceFALSE(NULL);
  201. #endif
  202. return fSuccess ? lpGarb : NULL;
  203. }
  204. // GarbGetHandle - verify that garb pointer is valid,
  205. // <lpGarb> (i) pointer to GARB struct
  206. // return corresponding garb handle (NULL if error)
  207. //
  208. static HGARB GarbGetHandle(LPGARB lpGarb)
  209. {
  210. BOOL fSuccess = TRUE;
  211. HGARB hGarb;
  212. if ((hGarb = (HGARB) lpGarb) == NULL)
  213. fSuccess = TraceFALSE(NULL);
  214. return fSuccess ? hGarb : NULL;
  215. }
  216. // GarbElemCreate - garbage element constructor
  217. // <elem> (i) data element
  218. // <dwFlags> (i) element flags (see GarbAddElement)
  219. // return pointer (NULL if error)
  220. //
  221. static LPGARBELEM GarbElemCreate(LPVOID elem, DWORD dwFlags)
  222. {
  223. BOOL fSuccess = TRUE;
  224. LPGARBELEM lpGarbElem;
  225. if ((lpGarbElem = (LPGARBELEM) MemAlloc(NULL, sizeof(GARBELEM), 0)) == NULL)
  226. fSuccess = TraceFALSE(NULL);
  227. else
  228. {
  229. lpGarbElem->elem = elem;
  230. lpGarbElem->dwFlags = dwFlags;
  231. }
  232. return fSuccess ? lpGarbElem : NULL;
  233. }
  234. // GarbElemDestroy - garbage element destructor
  235. // <lpGarbElem> (i) pointer returned from GarbElemCreate
  236. // return 0 if success
  237. //
  238. static int GarbElemDestroy(LPGARBELEM lpGarbElem)
  239. {
  240. BOOL fSuccess = TRUE;
  241. if (lpGarbElem == NULL)
  242. fSuccess = TraceFALSE(NULL);
  243. else
  244. {
  245. // dispose of temporary file
  246. //
  247. if (lpGarbElem->dwFlags & GARBELEM_TEMPFILENAME)
  248. {
  249. if (FileRemove((LPCTSTR) lpGarbElem->elem) != 0)
  250. fSuccess = TraceFALSE(NULL);
  251. }
  252. // dispose of string created by StrDup
  253. //
  254. if (lpGarbElem->dwFlags & GARBELEM_STRDUP &&
  255. lpGarbElem->elem != NULL)
  256. {
  257. if (StrDupFree((LPTSTR) lpGarbElem->elem) != 0)
  258. fSuccess = TraceFALSE(NULL);
  259. else
  260. lpGarbElem->elem = NULL;
  261. }
  262. // dispose of global memory block
  263. //
  264. if (lpGarbElem->dwFlags & GARBELEM_GLOBALPTR &&
  265. lpGarbElem->elem != NULL)
  266. {
  267. if (GlobalFreePtr(lpGarbElem->elem) != 0)
  268. fSuccess = TraceFALSE(NULL);
  269. else
  270. lpGarbElem->elem = NULL;
  271. }
  272. // dispose of local memory block
  273. //
  274. if (lpGarbElem->dwFlags & GARBELEM_LOCALPTR &&
  275. lpGarbElem->elem != NULL)
  276. {
  277. if (LocalFreePtr((NPSTR) LOWORD(lpGarbElem->elem)) != 0)
  278. fSuccess = TraceFALSE(NULL);
  279. else
  280. lpGarbElem->elem = NULL;
  281. }
  282. #ifdef _WIN32
  283. // dispose of heap memory block
  284. //
  285. if (lpGarbElem->dwFlags & GARBELEM_HEAPPTR &&
  286. lpGarbElem->elem != NULL)
  287. {
  288. if (!HeapFree(GetProcessHeap(), 0, lpGarbElem->elem))
  289. fSuccess = TraceFALSE(NULL);
  290. else
  291. lpGarbElem->elem = NULL;
  292. }
  293. #endif
  294. // dispose of cursor
  295. //
  296. if (lpGarbElem->dwFlags & GARBELEM_CURSOR &&
  297. lpGarbElem->elem != NULL)
  298. {
  299. if (!DestroyCursor((HCURSOR) lpGarbElem->elem))
  300. fSuccess = TraceFALSE(NULL);
  301. else
  302. lpGarbElem->elem = NULL;
  303. }
  304. // dispose of icon
  305. //
  306. if (lpGarbElem->dwFlags & GARBELEM_ICON &&
  307. lpGarbElem->elem != NULL)
  308. {
  309. if (!DestroyIcon((HICON) lpGarbElem->elem))
  310. fSuccess = TraceFALSE(NULL);
  311. else
  312. lpGarbElem->elem = NULL;
  313. }
  314. // dispose of menu
  315. //
  316. if (lpGarbElem->dwFlags & GARBELEM_MENU &&
  317. lpGarbElem->elem != NULL)
  318. {
  319. if (!DestroyMenu((HMENU) lpGarbElem->elem))
  320. fSuccess = TraceFALSE(NULL);
  321. else
  322. lpGarbElem->elem = NULL;
  323. }
  324. // dispose of window
  325. //
  326. if (lpGarbElem->dwFlags & GARBELEM_WINDOW &&
  327. lpGarbElem->elem != NULL)
  328. {
  329. if (!DestroyWindow((HWND) lpGarbElem->elem))
  330. fSuccess = TraceFALSE(NULL);
  331. else
  332. lpGarbElem->elem = NULL;
  333. }
  334. // dispose of display context
  335. //
  336. if (lpGarbElem->dwFlags & GARBELEM_DC &&
  337. lpGarbElem->elem != NULL)
  338. {
  339. if (!DeleteDC((HDC) lpGarbElem->elem))
  340. fSuccess = TraceFALSE(NULL);
  341. else
  342. lpGarbElem->elem = NULL;
  343. }
  344. // dispose of metafile
  345. //
  346. if (lpGarbElem->dwFlags & GARBELEM_METAFILE &&
  347. lpGarbElem->elem != NULL)
  348. {
  349. if (!DeleteMetaFile((HMETAFILE) lpGarbElem->elem))
  350. fSuccess = TraceFALSE(NULL);
  351. else
  352. lpGarbElem->elem = NULL;
  353. }
  354. // dispose of pen
  355. //
  356. if (lpGarbElem->dwFlags & GARBELEM_PEN &&
  357. lpGarbElem->elem != NULL)
  358. {
  359. if (!DeletePen((HPEN) lpGarbElem->elem))
  360. fSuccess = TraceFALSE(NULL);
  361. else
  362. lpGarbElem->elem = NULL;
  363. }
  364. // dispose of brush
  365. //
  366. if (lpGarbElem->dwFlags & GARBELEM_BRUSH &&
  367. lpGarbElem->elem != NULL)
  368. {
  369. if (!DeleteBrush((HBRUSH) lpGarbElem->elem))
  370. fSuccess = TraceFALSE(NULL);
  371. else
  372. lpGarbElem->elem = NULL;
  373. }
  374. // dispose of font
  375. //
  376. if (lpGarbElem->dwFlags & GARBELEM_FONT &&
  377. lpGarbElem->elem != NULL)
  378. {
  379. if (!DeleteFont((HFONT) lpGarbElem->elem))
  380. fSuccess = TraceFALSE(NULL);
  381. else
  382. lpGarbElem->elem = NULL;
  383. }
  384. // dispose of bitmap
  385. //
  386. if (lpGarbElem->dwFlags & GARBELEM_BITMAP &&
  387. lpGarbElem->elem != NULL)
  388. {
  389. if (!DeleteBitmap((HBITMAP) lpGarbElem->elem))
  390. fSuccess = TraceFALSE(NULL);
  391. else
  392. lpGarbElem->elem = NULL;
  393. }
  394. // dispose of region
  395. //
  396. if (lpGarbElem->dwFlags & GARBELEM_RGN &&
  397. lpGarbElem->elem != NULL)
  398. {
  399. if (!DeleteRgn((HRGN) lpGarbElem->elem))
  400. fSuccess = TraceFALSE(NULL);
  401. else
  402. lpGarbElem->elem = NULL;
  403. }
  404. // dispose of palette
  405. //
  406. if (lpGarbElem->dwFlags & GARBELEM_PALETTE &&
  407. lpGarbElem->elem != NULL)
  408. {
  409. if (!DeletePalette((HPALETTE) lpGarbElem->elem))
  410. fSuccess = TraceFALSE(NULL);
  411. else
  412. lpGarbElem->elem = NULL;
  413. }
  414. // dispose of file handle obtained from FileOpen or FileCreate
  415. //
  416. if (lpGarbElem->dwFlags & GARBELEM_HFIL &&
  417. lpGarbElem->elem != NULL)
  418. {
  419. if (FileClose((HFIL) lpGarbElem->elem) != 0)
  420. fSuccess = TraceFALSE(NULL);
  421. else
  422. lpGarbElem->elem = NULL;
  423. }
  424. // dispose of file handle obtained from OpenFile, _lopen or _lcreat
  425. //
  426. if (lpGarbElem->dwFlags & GARBELEM_HFILE &&
  427. lpGarbElem->elem != NULL)
  428. {
  429. if ( _lclose((HFILE) LOWORD(lpGarbElem->elem)) != 0 )
  430. fSuccess = TraceFALSE(NULL);
  431. else
  432. lpGarbElem->elem = NULL;
  433. }
  434. if ((lpGarbElem = MemFree(NULL, lpGarbElem)) != NULL)
  435. fSuccess = TraceFALSE(NULL);
  436. }
  437. return fSuccess ? 0 : -1;
  438. }