test: winprop.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# winprop.c

Go to the documentation of this file.

    00001 /****************************** Module Header ******************************\
    00002 * Module Name: winprop.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * This module contains routines having to do with window properties.
    00007 *
    00008 * History:
    00009 * 11-13-90 DarrinM      Created.
    00010 \***************************************************************************/
    00011
    00012 #include "precomp.h"
    00013 #pragma hdrstop
    00014
    00015 /***************************************************************************\
    00016 * InternalSetProp
    00017 *
    00018 * SetProp searches the linked-list of window property structures for the
    00019 * specified key.  If found, the existing property structure is changed to
    00020 * hold the new hData handle.  If no property is found with the specified key
    00021 * a new property structure is created and initialized.
    00022 *
    00023 * Since property keys are retained as atoms, we convert the incoming pszKey
    00024 * to an atom before lookup or storage.  pszKey might actually be an atom
    00025 * already, so we keep a flag, PROPF_STRING, so we know whether the atom was
    00026 * created by the system or whether it was passed in.  This way we know
    00027 * whether we should destroy it when the property is destroyed.
    00028 *
    00029 * Several property values are for User's private use.  These properties are
    00030 * denoted with the flag PROPF_INTERNAL.  Depending on the fInternal flag,
    00031 * either internal (User) or external (application) properties are set/get/
    00032 * removed/enumerated, etc.
    00033 *
    00034 * History:
    00035 * 11-14-90 darrinm      Rewrote from scratch with new data structures and
    00036 *                       algorithms.
    00037 \***************************************************************************/
    00038
    00039 BOOL InternalSetProp(
    00040     PWND pwnd,
    00041     LPWSTR pszKey,
    00042     HANDLE hData,
    00043     DWORD dwFlags)
    00044 {
    00045     PPROP pprop;
    00046
    00047     if (pszKey == NULL) {
    00048         RIPERR0(ERROR_INVALID_PARAMETER,
    00049                 RIP_WARNING,
    00050                 "Invalid parameter \"pszKey\" (NULL) to InternalSetProp");
    00051
    00052         return FALSE;
    00053     }
    00054
    00055     /*
    00056      * If no property list exists for this window, create one.
    00057      */
    00058     pprop = _FindProp(pwnd, pszKey, dwFlags & PROPF_INTERNAL);
    00059     if (pprop == NULL) {
    00060
    00061         /*
    00062          * pszKey must be an atom within the server.
    00063          */
    00064         UserAssert(!IS_PTR(pszKey));
    00065
    00066         /*
    00067          * CreateProp allocates the property and links it into the window's
    00068          * property list.
    00069          */
    00070         pprop = CreateProp(pwnd);
    00071         if (pprop == NULL)
    00072             return FALSE;
    00073
    00074         pprop->atomKey = PTR_TO_ID(pszKey);
    00075         pprop->fs = (WORD)dwFlags;
    00076     }
    00077
    00078     pprop->hData = hData;
    00079
    00080     return TRUE;
    00081 }
    00082
    00083
    00084 /***************************************************************************\
    00085 * InternalRemoveProp
    00086 *
    00087 * Remove the specified property from the specified window's property list.
    00088 * The property's hData handle is returned to the caller who can then free
    00089 * it or whatever.  NOTE: This also applies to internal properties as well --
    00090 * InternalRemoveProp will free the property structure and atom (if created
    00091 * by User) but will not free the hData itself.
    00092 *
    00093 * History:
    00094 * 11-14-90 darrinm      Rewrote from scratch with new data structures and
    00095 *                       algorithms.
    00096 \***************************************************************************/
    00097
    00098 HANDLE InternalRemoveProp(
    00099     PWND pwnd,
    00100     LPWSTR pszKey,
    00101     BOOL fInternal)
    00102 {
    00103     PPROP pprop;
    00104     PPROP ppropLast;
    00105     HANDLE hT;
    00106
    00107     /*
    00108      * Find the property to be removed.
    00109      */
    00110     pprop = _FindProp(pwnd, pszKey, fInternal);
    00111     if (pprop == NULL)
    00112         return NULL;
    00113
    00114     /*
    00115      * Remember what it was pointing at.
    00116      */
    00117     hT = pprop->hData;
    00118
    00119     /*
    00120      * Move the property at the end of the list into this slot.
    00121      */
    00122     pwnd->ppropList->iFirstFree--;
    00123     ppropLast = &pwnd->ppropList->aprop[pwnd->ppropList->iFirstFree];
    00124     *pprop = *ppropLast;
    00125     RtlZeroMemory(ppropLast, sizeof(*ppropLast));
    00126
    00127     return hT;
    00128 }
    00129
    00130
    00131 /***************************************************************************\
    00132 * _BuildPropList
    00133 *
    00134 * This is a unique client/server routine - it builds a list of Props and
    00135 * returns it to the client.  Unique since the client doesn't know how
    00136 * big the list is ahead of time.
    00137 *
    00138 * 29-Jan-1992 JohnC    Created.
    00139 \***************************************************************************/
    00140
    00141 NTSTATUS _BuildPropList(
    00142     PWND pwnd,
    00143     PROPSET aPropSet[],
    00144     UINT cPropMax,
    00145     PUINT pcPropNeeded)
    00146 {
    00147     UINT i;
    00148     PPROPLIST ppropList;
    00149     PPROP pProp;
    00150     DWORD iRetCnt = 0;            // The number of Props returned
    00151     DWORD iProp = 0;
    00152     PPROPSET pPropSetLast = (aPropSet + cPropMax - 1);
    00153     NTSTATUS Status;
    00154
    00155     /*
    00156      * If the Window does not have a property list then we're done
    00157      */
    00158     ppropList = pwnd->ppropList;
    00159     if (ppropList == NULL) {
    00160         *pcPropNeeded = 0;
    00161         return STATUS_SUCCESS;
    00162     }
    00163
    00164     /*
    00165      * For each element in the property list enumerate it.
    00166      * (only if it is not internal!)
    00167      */
    00168     Status = STATUS_SUCCESS;
    00169     pProp = ppropList->aprop;
    00170     for (i = ppropList->iFirstFree; i > 0; i--) {
    00171
    00172         /*
    00173          * if we run out of space in shared memory return
    00174          * STATUS_BUFFER_TOO_SMALL
    00175          */
    00176         if (&aPropSet[iProp] > pPropSetLast) {
    00177
    00178             /*
    00179              * Reset to the beginning of the output
    00180              * buffer so we can continue and compute
    00181              * the needed space.
    00182              */
    00183             iProp = 0;
    00184             Status = STATUS_BUFFER_TOO_SMALL;
    00185         }
    00186
    00187         if (!(pProp->fs & PROPF_INTERNAL)) {
    00188             aPropSet[iProp].hData = pProp->hData;
    00189             aPropSet[iProp].atom = pProp->atomKey;
    00190             iProp++;
    00191             iRetCnt++;
    00192         }
    00193         pProp++;
    00194     }
    00195
    00196     /*
    00197      * Return the number of PROPLISTs given back to the client
    00198      */
    00199
    00200     *pcPropNeeded = iRetCnt;
    00201
    00202     return Status;
    00203 }
    00204
    00205
    00206 /***************************************************************************\
    00207 * CreateProp
    00208 *
    00209 * Create a property structure and link it at the head of the specified
    00210 * window's property list.
    00211 *
    00212 * History:
    00213 * 11-14-90 darrinm      Rewrote from scratch with new data structures and
    00214 *                       algorithms.
    00215 \***************************************************************************/
    00216
    00217 PPROP CreateProp(
    00218     PWND pwnd)
    00219 {
    00220     PPROPLIST ppropList;
    00221     PPROP pprop;
    00222
    00223     if (pwnd->ppropList == NULL) {
    00224         pwnd->ppropList = (PPROPLIST)DesktopAlloc(pwnd->head.rpdesk,
    00225                                                   sizeof(PROPLIST),
    00226                                                   DTAG_PROPLIST);
    00227         if (pwnd->ppropList == NULL) {
    00228             return NULL;
    00229         }
    00230         pwnd->ppropList->cEntries = 1;
    00231     } else if (pwnd->ppropList->iFirstFree == pwnd->ppropList->cEntries) {
    00232         ppropList = (PPROPLIST)DesktopAlloc(pwnd->head.rpdesk,
    00233                                             sizeof(PROPLIST) + pwnd->ppropList->cEntries * sizeof(PROP),
    00234                                             DTAG_PROPLIST);
    00235         if (ppropList == NULL) {
    00236             return NULL;
    00237         }
    00238         RtlCopyMemory(ppropList, pwnd->ppropList, sizeof(PROPLIST) + (pwnd->ppropList->cEntries - 1) * sizeof(PROP));
    00239         DesktopFree(pwnd->head.rpdesk, pwnd->ppropList);
    00240         pwnd->ppropList = ppropList;
    00241         pwnd->ppropList->cEntries++;
    00242     }
    00243     pprop = &pwnd->ppropList->aprop[pwnd->ppropList->iFirstFree];
    00244     pwnd->ppropList->iFirstFree++;
    00245
    00246     return pprop;
    00247 }
    00248
    00249
    00250 /***************************************************************************\
    00251 * DeleteProperties
    00252 *
    00253 * When a window is destroyed we want to destroy all its accompanying
    00254 * properties.  DestroyProperties does this, including destroying any hData
    00255 * that was allocated by User for internal properties.  Any atoms created
    00256 * along with the properties are destroyed as well.  hData in application
    00257 * properties are not destroyed automatically; we assume the application
    00258 * is taking care of that itself (in its WM_DESTROY handler or similar).
    00259 *
    00260 * History:
    00261 * 11-14-90 darrinm      Rewrote from scratch with new data structures and
    00262 *                       algorithms.
    00263 \***************************************************************************/
    00264
    00265 void DeleteProperties(
    00266     PWND pwnd)
    00267 {
    00268     PPROP pprop;
    00269     UINT i;
    00270
    00271     UserAssert(pwnd->ppropList);
    00272
    00273     /*
    00274      * Loop through the whole list of properties on this window.
    00275      */
    00276     pprop = pwnd->ppropList->aprop;
    00277     for (i = pwnd->ppropList->iFirstFree; i > 0; i--) {
    00278
    00279         /*
    00280          * Is this an internal property?  If so, free any data we allocated
    00281          * for it.
    00282          */
    00283         if ((pprop->fs & PROPF_INTERNAL) && !(pprop->fs & PROPF_NOPOOL)) {
    00284                 UserFreePool(pprop->hData);
    00285         }
    00286
    00287         /*
    00288          * Advance to the next property in the list.
    00289          */
    00290         pprop++;
    00291     }
    00292
    00293     /*
    00294      * All properties gone, free the property list and clear out the
    00295      * window's property list pointer.
    00296      */
    00297     DesktopFree(pwnd->head.rpdesk, pwnd->ppropList);
    00298     pwnd->ppropList = NULL;
    00299 }
    00300