1 /* File: global_mem.c
2 **
3 ** This program is a test application used for testing correctness of the
4 ** GlobalXXX memory API implementation.
5 **
6 ** Programmer: Mark Tempel
7 */
8 #include <windows.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 /*
13 ** All output is line wrapped to fit a 80 column screen.
14 ** these defines control that formatting. To shrink the
15 ** screen columns, just change the DISPLAY_COMUMNS macro.
16 */
17 #define DISPLAY_COLUMNS 78
18 #define LINE_BUFFER_SIZE DISPLAY_COLUMNS + 2
19 
20 /*
21 ** This define controls the size of a memory allocation request.
22 ** For this test suite to really be comprehensive, we should
23 ** probably be testing many different block sizes.
24 */
25 #define MEM_BLOCK_SIZE 0x80000
26 
27 /*
28 ** This enumeration is really the return value for the program.
29 ** All test return a TestStatus and test statuses can be combined
30 ** with the relation TEST_CombineStatus.
31 */
32 typedef enum TestStatus
33 {
34     FAILED  = 0,
35     PASSED  = 1,
36     SKIPPED = -1
37 } TEST_STATUS;
38 
39 /*---------------------------------------------------------------------------
40 ** This is a relation used to combine two test statuses.
41 ** The combine rules are as follows:
42 **                   FAIL & Anything == FAIL
43 **                SKIPPED & Anything == Anything
44 **
45 */
46 TEST_STATUS TEST_CombineStatus(TEST_STATUS a, TEST_STATUS b)
47 {
48     TEST_STATUS result = a;
49 
50     switch (a)
51     {
52     case PASSED:  result = (PASSED == b || SKIPPED == b) ? (PASSED) : (FAILED); break;
53     case FAILED:  result = FAILED; break;
54     case SKIPPED: result = b; break;
55     }
56 
57     return result;
58 }
59 
60 /*---------------------------------------------------------------------------
61 ** This outputs the banner border lines.
62 */
63 void OUTPUT_BannerLine()
64 {
65     int c = 0;
66     printf("+");
67     for (c = 1; c < DISPLAY_COLUMNS; c++)
68     {
69         printf("-");
70     }
71     printf("\n");
72 }
73 
74 
75 /*---------------------------------------------------------------------------
76 ** This method prints a line that has a | on the left, and is line wrapped
77 ** to be no more that DISPLAY_COLUMNS +2 wide.
78 */
79 void OUTPUT_Line(const char *szLine)
80 {
81     int spaceIndex = 0;
82     char output[LINE_BUFFER_SIZE];
83 
84     memset(output, 0, DISPLAY_COLUMNS + 2);
85 
86     /*If this line is longer than DISPLAY_COLUMNS,
87     * break it at the first space.
88     */
89     if (DISPLAY_COLUMNS - 2 < strlen(szLine))
90     {
91         for (spaceIndex = DISPLAY_COLUMNS / 2; spaceIndex < DISPLAY_COLUMNS - 2; spaceIndex++)
92         {
93             if (' ' == szLine[spaceIndex])
94             {
95                 break;
96             }
97         }
98 
99         memcpy(output + 2, szLine, spaceIndex + 1);
100         output[0] = '|';
101         output[1] = ' ';
102         output[strlen(output)] = '\n';
103         printf(output);
104 
105         OUTPUT_Line(szLine + spaceIndex + 1);
106     }
107     else
108     {
109         sprintf(output,"| %s\n", szLine);
110         printf(output);
111     }
112 
113 }
114 
115 /*---------------------------------------------------------------------------
116 **
117 */
118 void OUTPUT_Banner(const char *szBanner)
119 {
120     OUTPUT_BannerLine();
121     OUTPUT_Line(szBanner);
122     OUTPUT_BannerLine();
123 }
124 
125 /*---------------------------------------------------------------------------
126 **
127 */
128 void OUTPUT_Result(TEST_STATUS status)
129 {
130     switch (status)
131     {
132     case PASSED:  OUTPUT_Line("==> PASSED"); break;
133     case FAILED:  OUTPUT_Line("*** FAILED"); break;
134     case SKIPPED: OUTPUT_Line("==> SKIPPED"); break;
135     }
136     OUTPUT_Line("");
137 }
138 
139 /*---------------------------------------------------------------------------
140 **
141 */
142 void OUTPUT_HexDword(DWORD dw)
143 {
144     char buffer[32];
145     sprintf(buffer, "0x%lX",dw);
146     OUTPUT_Line(buffer);
147 }
148 
149 void OUTPUT_Handle(HANDLE h)
150 {
151     char buffer[32];
152     sprintf(buffer, "0x%p", h);
153     OUTPUT_Line(buffer);
154 }
155 
156 /*---------------------------------------------------------------------------
157 **
158 */
159 void OutputAllocFlags(UINT pFlags)
160 {
161     if (pFlags & GMEM_MOVEABLE)
162     {
163         OUTPUT_Line("Movable Memory");
164     }
165     else
166     {
167         OUTPUT_Line("Fixed Memory");
168     }
169 
170     if (pFlags & GMEM_ZEROINIT)
171     {
172         OUTPUT_Line("Zero Initialized Memory");
173     }
174 }
175 
176 /*---------------------------------------------------------------------------
177 **
178 */
179 void OutputErrorCode()
180 {
181     char buffer[256];
182 
183     sprintf(buffer,"GetLastError() returned %lu", GetLastError());
184 
185     OUTPUT_Line(buffer);
186 }
187 /*---------------------------------------------------------------------------
188 **
189 */
190 TEST_STATUS TEST_MemoryWrite(LPVOID mem, DWORD cbSize)
191 {
192     TEST_STATUS result = FAILED;
193 
194     if (0 == IsBadWritePtr(mem, cbSize))
195     {
196         result = PASSED;
197     }
198     return result;
199 }
200 
201 /*---------------------------------------------------------------------------
202 **
203 */
204 TEST_STATUS TEST_MemoryRead(LPVOID mem, DWORD cbSize)
205 {
206     TEST_STATUS result = FAILED;
207 
208     if (0 == IsBadReadPtr(mem, cbSize))
209     {
210         result = PASSED;
211     }
212     return result;
213 }
214 
215 /*---------------------------------------------------------------------------
216 ** This method tests to see if a block of global memory is movable
217 ** by seeing if the value returned from GlobalLock is different from
218 ** the passed in value.
219 */
220 int IsMovable(HGLOBAL hMem)
221 {
222     LPVOID pMem = 0;
223     int    rc   = 0;
224 
225     pMem = GlobalLock(hMem);
226     if (pMem != hMem)
227     {
228         rc = 1;
229     }
230     GlobalUnlock(hMem);
231 
232     return rc;
233 }
234 
235 /*---------------------------------------------------------------------------
236 **
237 */
238 TEST_STATUS TestGlobalAllocNFree(UINT allocFlags)
239 {
240     TEST_STATUS status = SKIPPED;
241     HGLOBAL hTest = 0;
242     OUTPUT_Banner("Testing the GlobalAlloc and GlobalFree calls");
243     OUTPUT_Line("Allocate a buffer");
244 
245     OutputAllocFlags(allocFlags);
246 
247     status = FAILED;
248     hTest = GlobalAlloc(allocFlags, MEM_BLOCK_SIZE);
249     if (0 != hTest)
250     {
251         if (0 == GlobalFree(hTest))
252         {
253             status = PASSED;
254         }
255     }
256 
257     OUTPUT_Line("Result for this run:");
258     OUTPUT_Result(status);
259     OUTPUT_Line("");
260 
261     return status;
262 }
263 
264 /*---------------------------------------------------------------------------
265 **
266 */
267 TEST_STATUS TestGlobalLockNUnlock(UINT allocFlags)
268 {
269     HGLOBAL     hMem      = 0;
270     LPVOID      pMem      = 0;
271     TEST_STATUS subtest   = SKIPPED;
272     TEST_STATUS result    = FAILED;
273 
274     OUTPUT_Banner("Testing the GlobalLock/Unlock functions.");
275     OutputAllocFlags(allocFlags);
276     OUTPUT_Line("");
277 
278     hMem = GlobalAlloc(allocFlags, MEM_BLOCK_SIZE);
279     if (0 != hMem)
280     {
281         OUTPUT_Line("Allocated a memory block");
282 
283         OUTPUT_Line("Testing Lock");
284         pMem = GlobalLock(hMem);
285         if (0 != pMem)
286         {
287             OUTPUT_Result(PASSED);
288 
289             OUTPUT_Line("Testing memory for read.");
290             subtest = TEST_MemoryRead(pMem, MEM_BLOCK_SIZE);
291             OUTPUT_Result(subtest);
292             result = TEST_CombineStatus(PASSED, subtest);
293 
294 
295             OUTPUT_Line("Testing memory for write.");
296             subtest = TEST_MemoryRead(pMem, MEM_BLOCK_SIZE);
297             OUTPUT_Result(subtest);
298             result = TEST_CombineStatus(result, subtest);
299 
300 
301             OUTPUT_Line("Unlocking memory");
302             if (GlobalUnlock(hMem))
303             {
304                 OUTPUT_Result(PASSED);
305                 result = TEST_CombineStatus(result, PASSED);
306             }
307             else
308             {
309                 if (NO_ERROR == GetLastError())
310                 {
311                     OUTPUT_Result(PASSED);
312                     result = TEST_CombineStatus(result, PASSED);
313                 }
314                 else
315                 {
316                     OutputErrorCode();
317                     OUTPUT_Result(FAILED);
318                     result = TEST_CombineStatus(result, FAILED);
319                 }
320             }
321         }
322 
323         OUTPUT_Line("Freeing memory");
324         if (0 == GlobalFree(hMem))
325         {
326             OUTPUT_Result(PASSED);
327             result = TEST_CombineStatus(result, PASSED);
328         }
329         else
330         {
331             OutputErrorCode();
332             OUTPUT_Result(FAILED);
333             result = TEST_CombineStatus(result, FAILED);
334         }
335     }
336     return result;
337 }
338 
339 /*---------------------------------------------------------------------------
340 **
341 */
342 TEST_STATUS TestGlobalReAllocFixed()
343 {
344     HGLOBAL     hMem       = 0;
345     HGLOBAL     hReAlloced = 0;
346     LPVOID      pMem       = 0;
347     TEST_STATUS subtest    = SKIPPED;
348     TEST_STATUS result     = SKIPPED;
349 
350     OUTPUT_Line("Testing GlobalReAlloc() on memory allocated as GMEM_FIXED");
351 
352     /* Case 1: convert a fixed block to a movable block. */
353     OUTPUT_Line("Allocating buffer");
354     hMem = GlobalAlloc(GMEM_FIXED, MEM_BLOCK_SIZE);
355     if (0 != hMem)
356     {
357         OUTPUT_Line("Testing to see if this is converted into a movable block");
358         hReAlloced = GlobalReAlloc(hMem, MEM_BLOCK_SIZE + 100, GMEM_MOVEABLE | GMEM_MODIFY);
359         if (0 == hReAlloced)
360         {
361             OUTPUT_Line("GlobalReAlloc failed-- returned NULL");
362             subtest = TEST_CombineStatus(subtest, FAILED);
363             OUTPUT_Result(subtest);
364         }
365         else
366         {
367             hMem = hReAlloced;
368             if (0 == IsMovable(hMem))
369             {
370                 OUTPUT_Line("GlobalReAlloc returned a fixed pointer.");
371                 subtest = TEST_CombineStatus(subtest, FAILED);
372                 OUTPUT_Result(subtest);
373             }
374             else
375             {
376                 pMem = GlobalLock(hMem);
377                 subtest = TEST_CombineStatus(subtest, PASSED);
378                 subtest = TEST_CombineStatus(subtest, TEST_MemoryRead(pMem, MEM_BLOCK_SIZE + 100));
379                 if (FAILED == subtest)
380                 {
381                     OUTPUT_Line("Memory Read failed.");
382                 }
383                 subtest = TEST_CombineStatus(subtest, TEST_MemoryWrite(pMem, MEM_BLOCK_SIZE + 100));
384                 if (FAILED == subtest)
385                 {
386                     OUTPUT_Line("Memory Write failed.");
387                 }
388                 GlobalUnlock(hMem);
389             }
390         }
391 
392         GlobalFree(hMem);
393     }
394     else
395     {
396         OUTPUT_Line("Global Alloc Failed.");
397         subtest = TEST_CombineStatus(subtest, FAILED);
398     }
399     OUTPUT_Line("Subtest result:");
400     OUTPUT_Result(subtest);
401     OUTPUT_Line("");
402 
403     result = TEST_CombineStatus(result, subtest);
404     subtest = SKIPPED;
405 
406     /* case 2 only move a fixed block */
407     OUTPUT_Line("Allocating buffer");
408     hMem = GlobalAlloc(GMEM_FIXED, MEM_BLOCK_SIZE);
409     if (0 != hMem)
410     {
411         OUTPUT_Line("Testing to see if a new fixed block is returned.");
412         hReAlloced = GlobalReAlloc(hMem, MEM_BLOCK_SIZE - 100, GMEM_MOVEABLE);
413         if (0 == hReAlloced)
414         {
415             OUTPUT_Line("GlobalReAlloc failed-- returned NULL");
416             subtest = TEST_CombineStatus(subtest, FAILED);
417             OUTPUT_Result(subtest);
418         }
419         else
420         {
421             OUTPUT_Line("Alloced Handle: ");
422             OUTPUT_Handle(hMem);
423             OUTPUT_Line("ReAlloced Handle: ");
424             OUTPUT_Handle(hReAlloced);
425             if (hMem == hReAlloced)
426             {
427                 OUTPUT_Line("GlobalReAlloc returned the same pointer.  The documentation states that this is wrong, but Windows NT works this way.");
428             }
429 
430             hMem = hReAlloced;
431             subtest = TEST_CombineStatus(subtest, PASSED);
432             subtest = TEST_CombineStatus(subtest, TEST_MemoryRead((LPVOID)hMem, MEM_BLOCK_SIZE - 100));
433             subtest = TEST_CombineStatus(subtest, TEST_MemoryWrite((LPVOID)hMem, MEM_BLOCK_SIZE - 100));
434         }
435 
436         GlobalFree(hMem);
437     }
438     else
439     {
440         subtest = TEST_CombineStatus(subtest, FAILED);
441     }
442     OUTPUT_Line("Subtest result:");
443     OUTPUT_Result(subtest);
444     OUTPUT_Line("");
445 
446     result = TEST_CombineStatus(result, subtest);
447     subtest = SKIPPED;
448 
449     /* Case 3: re-allocate a fixed block in place */
450     OUTPUT_Line("Allocating buffer");
451     hMem = GlobalAlloc(GMEM_FIXED, MEM_BLOCK_SIZE);
452     if (0 != hMem)
453     {
454         OUTPUT_Line("Testing to see if a fixed pointer is reallocated in place.");
455         hReAlloced = GlobalReAlloc(hMem, MEM_BLOCK_SIZE - 100, 0);
456         if (0 == hReAlloced)
457         {
458             OUTPUT_Line("GlobalReAlloc failed-- returned NULL");
459             subtest = TEST_CombineStatus(subtest, FAILED);
460             OUTPUT_Result(subtest);
461         }
462         else
463         {
464             OUTPUT_Line("Alloced Handle: ");
465             OUTPUT_Handle(hMem);
466             OUTPUT_Line("ReAlloced Handle: ");
467             OUTPUT_Handle(hReAlloced);
468             if (hMem != hReAlloced)
469             {
470                 OUTPUT_Line("GlobalReAlloc returned a different.");
471                 subtest = TEST_CombineStatus(subtest, FAILED);
472                 OUTPUT_Result(subtest);
473             }
474             else
475             {
476                 subtest = TEST_CombineStatus(subtest, PASSED);
477                 subtest = TEST_CombineStatus(subtest, TEST_MemoryRead((LPVOID)hMem, MEM_BLOCK_SIZE - 100));
478                 subtest = TEST_CombineStatus(subtest, TEST_MemoryWrite((LPVOID)hMem, MEM_BLOCK_SIZE - 100));
479             }
480         }
481 
482         GlobalFree(hMem);
483     }
484     else
485     {
486         subtest = TEST_CombineStatus(subtest, FAILED);
487     }
488     OUTPUT_Line("Subtest result:");
489     OUTPUT_Result(subtest);
490     OUTPUT_Line("");
491 
492     result = TEST_CombineStatus(result, subtest);
493 
494     OUTPUT_Line("");
495     return result;
496 }
497 /*---------------------------------------------------------------------------
498 **
499 */
500 TEST_STATUS TestGlobalReAllocMovable()
501 {
502     HGLOBAL     hMem       = 0;
503     HGLOBAL     hReAlloced = 0;
504     LPVOID      pMem       = 0;
505     TEST_STATUS subtest    = SKIPPED;
506     TEST_STATUS result     = SKIPPED;
507 
508     OUTPUT_Line("Testing GlobalReAlloc() on memory allocated as GMGM_MOVEABLE");
509 
510     /* case 1 test reallocing a movable block that is unlocked. */
511     OUTPUT_Line("Allocating buffer");
512     hMem = GlobalAlloc(GMEM_MOVEABLE, MEM_BLOCK_SIZE);
513     if (0 != hMem)
514     {
515         OUTPUT_Line("Testing GlobalReAlloc on a unlocked block.");
516         hReAlloced = GlobalReAlloc(hMem, MEM_BLOCK_SIZE - 100, 0);
517         if (0 == hReAlloced)
518         {
519             OUTPUT_Line("GlobalReAlloc failed-- returned NULL");
520             subtest = TEST_CombineStatus(subtest, FAILED);
521             OUTPUT_Result(subtest);
522         }
523         else
524         {
525             OUTPUT_Line("Alloced Handle: ");
526             OUTPUT_Handle(hMem);
527             OUTPUT_Line("ReAlloced Handle: ");
528             OUTPUT_Handle(hReAlloced);
529 
530             pMem = GlobalLock(hReAlloced);
531             hMem = hReAlloced;
532             subtest = TEST_CombineStatus(subtest, PASSED);
533             subtest = TEST_CombineStatus(subtest, TEST_MemoryRead(pMem, MEM_BLOCK_SIZE - 100));
534             subtest = TEST_CombineStatus(subtest, TEST_MemoryWrite(pMem, MEM_BLOCK_SIZE - 100));
535             GlobalUnlock(hReAlloced);
536         }
537 
538         GlobalFree(hMem);
539     }
540     else
541     {
542         subtest = TEST_CombineStatus(subtest, FAILED);
543     }
544     OUTPUT_Line("Subtest result:");
545     OUTPUT_Result(subtest);
546     OUTPUT_Line("");
547 
548     result = TEST_CombineStatus(result, subtest);
549     subtest = SKIPPED;
550 
551     /* Case 2: re-allocate a moveable block that is locked */
552     OUTPUT_Line("Allocating buffer");
553     hMem = GlobalAlloc(GMEM_MOVEABLE, MEM_BLOCK_SIZE);
554     if (0 != hMem)
555     {
556 
557         OUTPUT_Line("Testing GlobalReAlloc on a locked block.");
558         pMem = GlobalLock(hMem);
559         hReAlloced = GlobalReAlloc(hMem, MEM_BLOCK_SIZE - 100, 0);
560         if (0 == hReAlloced)
561         {
562             OUTPUT_Line("GlobalReAlloc failed-- returned NULL");
563             subtest = TEST_CombineStatus(subtest, FAILED);
564             OUTPUT_Result(subtest);
565         }
566         else
567         {
568             OUTPUT_Line("Alloced Handle: ");
569             OUTPUT_Handle(hMem);
570             OUTPUT_Line("ReAlloced Handle: ");
571             OUTPUT_Handle(hReAlloced);
572             if (hMem != hReAlloced)
573             {
574                 OUTPUT_Line("GlobalReAlloc returned a different block.");
575             }
576             pMem = GlobalLock(hReAlloced);
577             subtest = TEST_CombineStatus(subtest, PASSED);
578             subtest = TEST_CombineStatus(subtest, TEST_MemoryRead(pMem, MEM_BLOCK_SIZE - 100));
579             subtest = TEST_CombineStatus(subtest, TEST_MemoryWrite(pMem , MEM_BLOCK_SIZE - 100));
580             GlobalUnlock(hReAlloced);
581 
582         }
583 
584         GlobalUnlock(hMem);
585 
586         GlobalFree(hMem);
587     }
588     else
589     {
590         subtest = TEST_CombineStatus(subtest, FAILED);
591     }
592     OUTPUT_Line("Subtest result:");
593     OUTPUT_Result(subtest);
594     OUTPUT_Line("");
595 
596     result = TEST_CombineStatus(result, subtest);
597 
598     OUTPUT_Line("");
599     return result;
600 }
601 
602 /*---------------------------------------------------------------------------
603 **
604 */
605 TEST_STATUS TestGlobalReAlloc()
606 {
607     TEST_STATUS result = SKIPPED;
608     OUTPUT_Banner("Testing GlobalReAlloc()");
609 
610     result = TEST_CombineStatus(result, TestGlobalReAllocFixed());
611     result = TEST_CombineStatus(result, TestGlobalReAllocMovable());
612 
613     OUTPUT_Line("GlobalReAlloc test result:");
614     OUTPUT_Result(result);
615     return result;
616 }
617 
618 /*---------------------------------------------------------------------------
619 **
620 */
621 TEST_STATUS TestGlobalFlagsMoveable()
622 {
623     HGLOBAL     hMem   = 0;
624     UINT        uFlags = 0;
625     TEST_STATUS result = SKIPPED;
626 
627     OUTPUT_Line("Test for the proper lock count");
628 
629     hMem = GlobalAlloc(GMEM_MOVEABLE, MEM_BLOCK_SIZE);
630     if (0 != hMem)
631     {
632 
633         OUTPUT_Line("Testing initial allocation");
634 
635         OUTPUT_Line("Testing for a lock of 0");
636         uFlags = GlobalFlags(hMem);
637         if (((GMEM_LOCKCOUNT & uFlags) == 0)) /*no locks*/
638         {
639             result = TEST_CombineStatus(result, PASSED);
640         }
641         else
642         {
643             result = TEST_CombineStatus(result, FAILED);
644         }
645         OUTPUT_Result(result);
646 
647         OUTPUT_Line("Pointer from handle: ");
648         OUTPUT_Handle(GlobalLock(hMem));
649 
650         OUTPUT_Line("Testing after a lock");
651         OUTPUT_Line("Testing for a lock of 1");
652         uFlags = GlobalFlags(hMem);
653         if (((GMEM_LOCKCOUNT & uFlags) == 1)) /*no locks*/
654         {
655             result = TEST_CombineStatus(result, PASSED);
656         }
657         else
658         {
659             result = TEST_CombineStatus(result, FAILED);
660         }
661         OUTPUT_Result(result);
662 
663         GlobalUnlock(hMem);
664         OUTPUT_Line("Testing after an unlock");
665         OUTPUT_Line("Testing for a lock of 0");
666         uFlags = GlobalFlags(hMem);
667         if (((GMEM_LOCKCOUNT & uFlags) == 0)) /*no locks*/
668         {
669             result = TEST_CombineStatus(result, PASSED);
670         }
671         else
672         {
673             result = TEST_CombineStatus(result, FAILED);
674         }
675         OUTPUT_Result(result);
676     }
677     else
678     {
679         OUTPUT_Line("GlobalAlloc failed!");
680         result = TEST_CombineStatus(result, FAILED);
681     }
682 
683     OUTPUT_Line("Test for discarded memory");
684     OUTPUT_Line("Allocating an empty moveable block---automatically marked as discarded");
685     hMem = GlobalAlloc(GMEM_MOVEABLE, 0); /*allocate a discarded block*/
686     if (0 != hMem)
687     {
688         OUTPUT_Line("Allocation handle: ");
689         OUTPUT_Handle(hMem);
690         OUTPUT_Line("Testing for a discarded flag");
691         uFlags = GlobalFlags(hMem);
692         if (0 != (uFlags & GMEM_DISCARDED)) /*discarded*/
693         {
694             result = TEST_CombineStatus(result, PASSED);
695         }
696         else
697         {
698             result = TEST_CombineStatus(result, FAILED);
699         }
700         OUTPUT_Line("Flags:");
701         OUTPUT_HexDword(uFlags);
702         OUTPUT_Result(result);
703 
704         GlobalFree(hMem);
705     }
706     else
707     {
708         OUTPUT_Line("GlobalAlloc failed!");
709         result = TEST_CombineStatus(result, FAILED);
710     }
711     return result;
712 }
713 
714 
715 /*---------------------------------------------------------------------------
716 **
717 */
718 TEST_STATUS TestGlobalFlagsFixed()
719 {
720     HGLOBAL     hMem   = 0;
721     UINT        uFlags = 0;
722     TEST_STATUS result = SKIPPED;
723 
724     OUTPUT_Line("Testing for correct handling of GMEM_FIXED memory");
725     hMem = GlobalAlloc(GMEM_FIXED, MEM_BLOCK_SIZE);
726     if (0 != hMem)
727     {
728 
729         OUTPUT_Line("Allocation handle: ");
730         OUTPUT_Handle(hMem);
731 
732         OUTPUT_Line("Testing initial allocation");
733         OUTPUT_Line("Testing for non-discarded and lock of 0");
734         uFlags = GlobalFlags(hMem);
735         if (((GMEM_LOCKCOUNT & uFlags) == 0) && /*no locks*/
736             (((uFlags >> 8) & 0xff) == 0 ))   /*not discarded*/
737         {
738             result = TEST_CombineStatus(result, PASSED);
739         }
740         else
741         {
742             result = TEST_CombineStatus(result, FAILED);
743         }
744         OUTPUT_Result(result);
745 
746         OUTPUT_Line("Pointer from handle: ");
747         OUTPUT_Handle(GlobalLock(hMem));
748         OUTPUT_Line("Testing after a lock");
749         OUTPUT_Line("Testing for non-discarded and lock of 0");
750         uFlags = GlobalFlags(hMem);
751         if (((GMEM_LOCKCOUNT & uFlags) == 0) && /*no locks*/
752             (((uFlags >> 8) & 0xff) == 0 ))   /*not discarded*/
753         {
754             result = TEST_CombineStatus(result, PASSED);
755         }
756         else
757         {
758             result = TEST_CombineStatus(result, FAILED);
759         }
760         OUTPUT_Result(result);
761 
762         GlobalFree(hMem);
763     }
764     else
765     {
766         OUTPUT_Line("GlobalAlloc failed!");
767         result = TEST_CombineStatus(result, FAILED);
768     }
769 
770     return result;
771 }
772 /*---------------------------------------------------------------------------
773 **
774 */
775 TEST_STATUS TestGlobalFlags()
776 {
777     TEST_STATUS result = SKIPPED;
778     OUTPUT_Banner("Testing GlobalFlags()");
779 
780     result = TEST_CombineStatus(result, TestGlobalFlagsFixed());
781     result = TEST_CombineStatus(result, TestGlobalFlagsMoveable());
782 
783     OUTPUT_Line("GlobalFlags result:");
784     OUTPUT_Result(result);
785     return result;
786 }
787 /*---------------------------------------------------------------------------
788 **
789 */
790 TEST_STATUS TestGlobalHandle()
791 {
792     HGLOBAL     hMem    = 0;
793     HGLOBAL     hTest   = 0;
794     PVOID       pMem    = 0;
795     TEST_STATUS subtest = SKIPPED;
796     TEST_STATUS result  = SKIPPED;
797 
798     OUTPUT_Banner("Testing GlobalHandle()");
799 
800     OUTPUT_Line("Testing GlobalHandle with a block of GMEM_FIXED memory");
801     hMem = GlobalAlloc(GMEM_FIXED, MEM_BLOCK_SIZE);
802     if (0 != hMem)
803     {
804 
805         OUTPUT_Line("Allocation handle: ");
806         OUTPUT_Handle(hMem);
807 
808         hTest = GlobalHandle(hMem);
809         if (hMem == hTest)
810         {
811             subtest = TEST_CombineStatus(subtest, PASSED);
812         }
813         else
814         {
815             OUTPUT_Line("GlobalHandle returned:");
816             OUTPUT_Handle(hTest);
817             subtest = TEST_CombineStatus(subtest, FAILED);
818         }
819 
820         GlobalFree(hMem);
821     }
822     else
823     {
824         OUTPUT_Line("GlobalAlloc failed!");
825         subtest = TEST_CombineStatus(subtest, FAILED);
826     }
827 
828     OUTPUT_Line("Result from subtest:");
829     OUTPUT_Result(subtest);
830     result = TEST_CombineStatus(result, subtest);
831 
832 
833     subtest = SKIPPED;
834     OUTPUT_Line("Testing GlobalHandle with a block of GMEM_MOVEABLE memory");
835     hMem = GlobalAlloc(GMEM_MOVEABLE, MEM_BLOCK_SIZE);
836     if (0 != hMem)
837     {
838 
839         OUTPUT_Line("Allocation handle: ");
840         OUTPUT_Handle(hMem);
841         pMem = GlobalLock(hMem);
842         hTest = GlobalHandle(pMem);
843         if (hMem == hTest)
844         {
845             subtest = TEST_CombineStatus(subtest, PASSED);
846         }
847         else
848         {
849             OUTPUT_Line("GlobalHandle returned:");
850             OUTPUT_Handle(hTest);
851             subtest = TEST_CombineStatus(subtest, FAILED);
852         }
853 
854         GlobalUnlock(hMem);
855         GlobalFree(hMem);
856     }
857     else
858     {
859         OUTPUT_Line("GlobalAlloc failed!");
860         subtest = TEST_CombineStatus(subtest, FAILED);
861     }
862 
863     OUTPUT_Line("Result from subtest:");
864     OUTPUT_Result(subtest);
865     result = TEST_CombineStatus(result, subtest);
866 
867 
868     OUTPUT_Line("Global Handle test results:");
869     OUTPUT_Result(result);
870     return result;
871 }
872 
873 /*---------------------------------------------------------------------------
874 **
875 */
876 TEST_STATUS TestGlobalSize()
877 {
878     HGLOBAL hMem = 0;
879     SIZE_T  size = 0;
880     TEST_STATUS subtest = SKIPPED;
881     TEST_STATUS result  = SKIPPED;
882     OUTPUT_Banner("Testing GlobalSize()");
883 
884     OUTPUT_Line("Testing GlobalSize with a block of GMEM_FIXED memory");
885     hMem = GlobalAlloc(GMEM_FIXED, MEM_BLOCK_SIZE);
886     if (0 != hMem)
887     {
888         size = GlobalSize(hMem);
889         if (MEM_BLOCK_SIZE <= size)
890         {
891             subtest = TEST_CombineStatus(subtest, PASSED);
892         }
893         else
894         {
895             OUTPUT_Line("GlobalSize returned:");
896             OUTPUT_HexDword(size);
897             subtest = TEST_CombineStatus(subtest, FAILED);
898         }
899 
900         GlobalFree(hMem);
901     }
902     else
903     {
904         OUTPUT_Line("GlobalAlloc failed!");
905         subtest = TEST_CombineStatus(subtest, FAILED);
906     }
907 
908     OUTPUT_Line("Result from subtest:");
909     OUTPUT_Result(subtest);
910     result = TEST_CombineStatus(result, subtest);
911 
912     OUTPUT_Line("Testing GlobalSize with a block of GMEM_MOVEABLE memory");
913     hMem = GlobalAlloc(GMEM_MOVEABLE, MEM_BLOCK_SIZE);
914     if (0 != hMem)
915     {
916         size = GlobalSize(hMem);
917         if (MEM_BLOCK_SIZE <= size)
918         {
919             subtest = TEST_CombineStatus(subtest, PASSED);
920         }
921         else
922         {
923             OUTPUT_Line("GlobalSize returned:");
924             OUTPUT_HexDword(size);
925             subtest = TEST_CombineStatus(subtest, FAILED);
926         }
927 
928         GlobalFree(hMem);
929     }
930     else
931     {
932         OUTPUT_Line("GlobalAlloc failed!");
933         subtest = TEST_CombineStatus(subtest, FAILED);
934     }
935 
936     OUTPUT_Line("Result from subtest:");
937     OUTPUT_Result(subtest);
938     result = TEST_CombineStatus(result, subtest);
939 
940     OUTPUT_Line("Testing GlobalSize with discarded memory");
941     hMem = GlobalAlloc(GMEM_MOVEABLE, 0);
942     if (0 != hMem)
943     {
944         size = GlobalSize(hMem);
945         if (0 == size)
946         {
947             subtest = TEST_CombineStatus(subtest, PASSED);
948         }
949         else
950         {
951             OUTPUT_Line("GlobalSize returned:");
952             OUTPUT_HexDword(size);
953             subtest = TEST_CombineStatus(subtest, FAILED);
954         }
955 
956         GlobalFree(hMem);
957     }
958     else
959     {
960         OUTPUT_Line("GlobalAlloc failed!");
961         subtest = TEST_CombineStatus(subtest, FAILED);
962     }
963 
964     OUTPUT_Line("Result from subtest:");
965     OUTPUT_Result(subtest);
966     result = TEST_CombineStatus(result, subtest);
967 
968     OUTPUT_Line("Test result:");
969     OUTPUT_Result(result);
970     return result;
971 }
972 
973 /*---------------------------------------------------------------------------
974 **
975 */
976 TEST_STATUS TestGlobalDiscard()
977 {
978     HGLOBAL     hMem    = 0;
979     HGLOBAL     hTest   = 0;
980     DWORD       uFlags  = 0;
981     TEST_STATUS subtest = SKIPPED;
982     TEST_STATUS result  = SKIPPED;
983 
984     OUTPUT_Banner("Testing GlobalDiscard()");
985     hMem = GlobalAlloc(GMEM_MOVEABLE, MEM_BLOCK_SIZE);
986     if (0 != hMem)
987     {
988         OUTPUT_Line("Allocation handle: ");
989         OUTPUT_Handle(hMem);
990 
991         hTest = GlobalDiscard(hMem);
992         if (0 == hTest)
993         {
994             OUTPUT_Line("GlobalDiscard returned NULL");
995             subtest = TEST_CombineStatus(subtest, FAILED);
996         }
997         else
998         {
999             uFlags = GlobalFlags(hTest);
1000             OUTPUT_Line("Flags from the new memory block.");
1001             OUTPUT_HexDword(uFlags);
1002             if (0 != (uFlags & GMEM_DISCARDED))
1003             {
1004                 subtest = TEST_CombineStatus(subtest, PASSED);
1005             }
1006             else
1007             {
1008                 OUTPUT_Line("Block is not marked as discardable.");
1009                 subtest = TEST_CombineStatus(subtest, FAILED);
1010             }
1011         }
1012 
1013         GlobalFree(hTest);
1014     }
1015     else
1016     {
1017         OUTPUT_Line("GlobalAlloc failed!");
1018         subtest = TEST_CombineStatus(subtest, FAILED);
1019     }
1020 
1021     OUTPUT_Line("Result from subtest:");
1022     OUTPUT_Result(subtest);
1023 
1024     result = TEST_CombineStatus(result, subtest);
1025 
1026     OUTPUT_Result(result);
1027     return result;
1028 }
1029 
1030 /*---------------------------------------------------------------------------
1031 **
1032 */
1033 int main(int argc, char ** argv)
1034 {
1035     TEST_STATUS test_set = SKIPPED;
1036     OUTPUT_Banner("Testing GlobalXXX memory management functions.");
1037 
1038     test_set = TEST_CombineStatus(test_set, TestGlobalAllocNFree(GPTR));
1039     test_set = TEST_CombineStatus(test_set, TestGlobalAllocNFree(GHND));
1040     test_set = TEST_CombineStatus(test_set, TestGlobalAllocNFree(GMEM_FIXED));
1041     test_set = TEST_CombineStatus(test_set, TestGlobalAllocNFree(GMEM_MOVEABLE));
1042 
1043     if (FAILED == test_set)
1044     {
1045         OUTPUT_Line("Skipping any further tests.  GlobalAlloc/Free fails.");
1046         OUTPUT_Result(test_set);
1047         return test_set;
1048     }
1049 
1050     test_set = TEST_CombineStatus(test_set, TestGlobalLockNUnlock(GPTR));
1051     test_set = TEST_CombineStatus(test_set, TestGlobalLockNUnlock(GHND));
1052     test_set = TEST_CombineStatus(test_set, TestGlobalLockNUnlock(GMEM_FIXED));
1053     test_set = TEST_CombineStatus(test_set, TestGlobalLockNUnlock(GMEM_MOVEABLE));
1054 
1055     test_set = TEST_CombineStatus(test_set, TestGlobalReAlloc());
1056 
1057     test_set = TEST_CombineStatus(test_set, TestGlobalFlags());
1058 
1059     test_set = TEST_CombineStatus(test_set, TestGlobalHandle());
1060 
1061     test_set = TEST_CombineStatus(test_set, TestGlobalSize());
1062 
1063     test_set = TEST_CombineStatus(test_set, TestGlobalDiscard());
1064 
1065     /* output the result for the entire set of tests*/
1066     OUTPUT_Banner("Test suite result");
1067     OUTPUT_Result(test_set);
1068     return test_set;
1069 }
1070