//********************************************************************* //* Microsoft Windows ** //* Copyright(c) Microsoft Corp., 1993 ** //********************************************************************* #include "admincfg.h" CLASSLIST gClassList; /******************************************************************* Memory Management Strategy: Information about categories, policies and settings are stored in tables. Each table has one global handle and is moveable (so it must be locked before use). Tables contain a table header, a TABLEHDR struct, followed by zero or more variable-length table entries. The TABLEHDR contains the size in bytes and the number of entries in the table. Entries in a table contain information such as the name of the entry, and a handle to a sub-table. For instance, a category entry will have the name of the category and a handle to a table of policies for that category. When that category is selected, the policies in its sub-table will be displayed. Similarly, each policy has a handle to a sub-table which is a table of settings. (Settings do not have any subcomponents, so they always have a NULL subtable.) A graphic representation is: (category table) +-----------------+ | TABLEHDR | +-----------------+ | CATEGORY 0 | | Subtable Handle------------------> +-----------------+ | other data | | TABLEHDR | +-----------------+ +-----------------+ | CATEGORY 1 | | POLICY 0 | | Subtable Handle-------> +-----------------+le Handle--->etc. | other data | | TABLEHDR | data | +-----------------+ +-----------------+----------+ | CATEGORY 2 | | POLICY 0 | | | Subtable Handle-->etc. | Subtable Handle------> +----------------+ | other data | | Other data | | TABLEHDR | | | +-----------------+ +----------------+ | POLICY 1 | | SETTING 0 | | Subtable Handle-->etc. | Data | | Other data | +----------------+ | | ********************************************************************/ /******************************************************************* NAME: FreeTable SYNOPSIS: Frees the specified table and all sub-tables of that table. NOTES: Walks through the table entries and calls itself to recursively free sub-tables. EXIT: Returns TRUE if successful, FALSE if a memory error occurs. ********************************************************************/ BOOL FreeTable(TABLEENTRY * pTableEntry) { TABLEENTRY * pNext = pTableEntry->pNext; // free all children if (pTableEntry->pChild) FreeTable(pTableEntry->pChild); GlobalFree(pTableEntry); if (pNext) FreeTable(pNext); return TRUE; } BOOL InitializeRootTables( VOID ) { memset(&gClassList,0,sizeof(gClassList)); gClassList.pMachineCategoryList = (TABLEENTRY *) GlobalAlloc(GPTR,sizeof(TABLEENTRY)); gClassList.pUserCategoryList = (TABLEENTRY *) GlobalAlloc(GPTR,sizeof(TABLEENTRY)); if (!gClassList.pMachineCategoryList || !gClassList.pUserCategoryList) { if (gClassList.pMachineCategoryList) GlobalFree(gClassList.pMachineCategoryList); if (gClassList.pUserCategoryList) GlobalFree(gClassList.pUserCategoryList); return FALSE; } gClassList.pMachineCategoryList->dwSize = gClassList.pUserCategoryList->dwSize = sizeof(TABLEENTRY); gClassList.pMachineCategoryList->dwType = gClassList.pUserCategoryList->dwType = ETYPE_ROOT; return TRUE; } VOID FreeRootTables( VOID ) { if (gClassList.pMachineCategoryList) { FreeTable(gClassList.pMachineCategoryList); gClassList.pMachineCategoryList = NULL; } if (gClassList.pUserCategoryList) { FreeTable(gClassList.pUserCategoryList); gClassList.pUserCategoryList = NULL; } }