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

clenum.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: clenum 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * For enumeration functions 00007 * 00008 * 04-27-91 ScottLu Created. 00009 \***************************************************************************/ 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 00015 #define IEP_UNICODE 0x1 // Convert Atom to unicode string (vs ANSI) 00016 #define IEP_ENUMEX 0x2 // Pass lParam back to callback function (vs no lParam) 00017 00018 HWND *phwndCache = NULL; 00019 00020 00021 /***************************************************************************\ 00022 * InternalEnumWindows 00023 * 00024 * Calls server and gets back a window list. This list is enumerated, for each 00025 * window the callback address is called (into the application), until either 00026 * end-of-list is reached or FALSE is return ed. lParam is passed into the 00027 * callback function for app reference. 00028 * 00029 * 00030 * If any windows are returned (cHwnd > 0) the caller is responsible for 00031 * freeing the window buffer when done with the list 00032 * 00033 * 00034 * 04-27-91 ScottLu Created. 00035 \***************************************************************************/ 00036 00037 DWORD BuildHwndList( 00038 HDESK hdesk, 00039 HWND hwndNext, 00040 BOOL fEnumChildren, 00041 DWORD idThread, 00042 HWND **pphwndFirst) 00043 { 00044 UINT cHwnd; 00045 HWND *phwndFirst; 00046 NTSTATUS Status; 00047 int cTries; 00048 00049 /* 00050 * Allocate a buffer to hold the names. 00051 */ 00052 cHwnd = 64; 00053 phwndFirst = (HWND *)InterlockedExchangePointer(&(PVOID)phwndCache, 0); 00054 if (phwndFirst == NULL) { 00055 phwndFirst = UserLocalAlloc(0, cHwnd * sizeof(HWND)); 00056 if (phwndFirst == NULL) 00057 return 0; 00058 } 00059 00060 Status = NtUserBuildHwndList(hdesk, hwndNext, fEnumChildren, 00061 idThread, cHwnd, phwndFirst, &cHwnd); 00062 00063 /* 00064 * If the buffer wasn't big enough, reallocate 00065 * the buffer and try again. 00066 */ 00067 cTries = 0; 00068 while (Status == STATUS_BUFFER_TOO_SMALL) { 00069 UserLocalFree(phwndFirst); 00070 00071 /* 00072 * If we can't seem to get it right, 00073 * call it quits 00074 */ 00075 if (cTries++ == 10) 00076 return 0; 00077 00078 phwndFirst = UserLocalAlloc(0, cHwnd * sizeof(HWND)); 00079 if (phwndFirst == NULL) 00080 return 0; 00081 00082 Status = NtUserBuildHwndList(hdesk, hwndNext, fEnumChildren, 00083 idThread, cHwnd, phwndFirst, &cHwnd); 00084 } 00085 00086 if (!NT_SUCCESS(Status) || cHwnd <= 1) { 00087 UserLocalFree(phwndFirst); 00088 return 0; 00089 } 00090 00091 *pphwndFirst = phwndFirst; 00092 return cHwnd - 1; 00093 } 00094 00095 BOOL InternalEnumWindows( 00096 HDESK hdesk, 00097 HWND hwnd, 00098 WNDENUMPROC lpfn, 00099 LPARAM lParam, 00100 DWORD idThread, 00101 BOOL fEnumChildren) 00102 { 00103 UINT i; 00104 UINT cHwnd; 00105 HWND *phwndT; 00106 HWND *phwndFirst; 00107 BOOL fSuccess = TRUE; 00108 00109 /* 00110 * Get the hwnd list. It is returned in a block of memory 00111 * allocated with LocalAlloc. 00112 */ 00113 if ((cHwnd = BuildHwndList(hdesk, hwnd, fEnumChildren, idThread, 00114 &phwndFirst)) == -1) { 00115 return FALSE; 00116 } 00117 00118 /* 00119 * In Win 3.1 it was not an error if there were no windows in the thread 00120 */ 00121 if (cHwnd == 0) { 00122 if (idThread == 0) 00123 return FALSE; 00124 else 00125 return TRUE; 00126 } 00127 00128 00129 /* 00130 * Loop through the windows, call the function pointer back for each 00131 * one. End loop if either FALSE is return ed or the end-of-list is 00132 * reached. 00133 */ 00134 phwndT = phwndFirst; 00135 for (i = 0; i < cHwnd; i++) { 00136 00137 /* 00138 * call ValidateHwnd instead of RevalidateHwnd so that 00139 * restricted processes don't see handles they are not 00140 * suppose to see. 00141 */ 00142 if (ValidateHwnd(*phwndT)) { 00143 if (!(fSuccess = (*lpfn)(*phwndT, lParam))) 00144 break; 00145 } 00146 phwndT++; 00147 } 00148 00149 /* 00150 * Free up buffer and return status - TRUE if entire list was enumerated, 00151 * FALSE otherwise. 00152 */ 00153 phwndT = (HWND *)InterlockedExchangePointer(&(PVOID)phwndCache, phwndFirst); 00154 if (phwndT != NULL) { 00155 UserLocalFree(phwndT); 00156 } 00157 return fSuccess; 00158 } 00159 00160 00161 /***************************************************************************\ 00162 * EnumWindows 00163 * 00164 * Enumerates all top-level windows. Calls back lpfn with each hwnd until 00165 * either end-of-list or FALSE is return ed. lParam is passed into callback 00166 * function for app reference. 00167 * 00168 * 04-27-91 ScottLu Created. 00169 \***************************************************************************/ 00170 00171 BOOL WINAPI EnumWindows( 00172 WNDENUMPROC lpfn, 00173 LPARAM lParam) 00174 { 00175 return InternalEnumWindows(NULL, NULL, lpfn, lParam, 0L, FALSE); 00176 } 00177 00178 /***************************************************************************\ 00179 * EnumChildWindows 00180 * 00181 * Enumerates all children of the passed in window. Calls back lpfn with each 00182 * hwnd until either end-of-list or FALSE is return ed. lParam is passed into 00183 * callback function for app reference. 00184 * 00185 * 04-27-91 ScottLu Created. 00186 \***************************************************************************/ 00187 00188 BOOL WINAPI EnumChildWindows( 00189 HWND hwnd, 00190 WNDENUMPROC lpfn, 00191 LPARAM lParam) 00192 { 00193 return InternalEnumWindows(NULL, hwnd, lpfn, lParam, 0L, TRUE); 00194 } 00195 00196 /***************************************************************************\ 00197 * EnumThreadWindows 00198 * 00199 * Enumerates all top level windows created by idThread. Calls back lpfn with 00200 * each hwnd until either end-of-list or FALSE is return ed. lParam is passed 00201 * into callback function for app reference. 00202 * 00203 * 06-23-91 ScottLu Created. 00204 \***************************************************************************/ 00205 00206 BOOL EnumThreadWindows( 00207 DWORD idThread, 00208 WNDENUMPROC lpfn, 00209 LPARAM lParam) 00210 { 00211 return InternalEnumWindows(NULL, NULL, lpfn, lParam, idThread, FALSE); 00212 } 00213 00214 /***************************************************************************\ 00215 * EnumDesktopWindows 00216 * 00217 * Enumerates all top level windows on the desktop specified by hdesk. 00218 * Calls back lpfn with each hwnd until either end-of-list or FALSE 00219 * is returned. lParam is passed into callback function for app reference. 00220 * 00221 * 10-10-94 JimA Created. 00222 \***************************************************************************/ 00223 00224 BOOL EnumDesktopWindows( 00225 HDESK hdesk, 00226 WNDENUMPROC lpfn, 00227 LPARAM lParam) 00228 { 00229 return InternalEnumWindows(hdesk, NULL, lpfn, lParam, 0, FALSE); 00230 } 00231 00232 00233 00234 00235 /***************************************************************************\ 00236 * InternalEnumProps 00237 * 00238 * Calls server and gets back a list of props for the specified window. 00239 * The callback address is called (into the application), until either 00240 * end-of-list is reached or FALSE is return ed. 00241 * lParam is passed into the callback function for app reference when 00242 * IEP_ENUMEX is set. Atoms are turned into UNICODE string if IEP_UNICODE 00243 * is set. 00244 * 00245 * 22-Jan-1992 JohnC Created. 00246 \***************************************************************************/ 00247 00248 #define MAX_ATOM_SIZE 512 00249 #define ISSTRINGATOM(atom) ((WORD)(atom) >= 0xc000) 00250 00251 INT InternalEnumProps( 00252 HWND hwnd, 00253 PROPENUMPROC lpfn, 00254 LPARAM lParam, 00255 UINT flags) 00256 { 00257 DWORD ii; 00258 DWORD cPropSets; 00259 PPROPSET pPropSet; 00260 WCHAR awch[MAX_ATOM_SIZE]; 00261 PVOID pKey; 00262 INT iRetVal; 00263 DWORD cchName; 00264 NTSTATUS Status; 00265 int cTries; 00266 00267 /* 00268 * Allocate a buffer to hold the names. 00269 */ 00270 cPropSets = 32; 00271 pPropSet = UserLocalAlloc(0, cPropSets * sizeof(PROPSET)); 00272 if (pPropSet == NULL) 00273 return -1; 00274 00275 Status = NtUserBuildPropList(hwnd, cPropSets, pPropSet, &cPropSets); 00276 00277 /* 00278 * If the buffer wasn't big enough, reallocate 00279 * the buffer and try again. 00280 */ 00281 cTries = 0; 00282 while (Status == STATUS_BUFFER_TOO_SMALL) { 00283 UserLocalFree(pPropSet); 00284 00285 /* 00286 * If we can't seem to get it right, 00287 * call it quits 00288 */ 00289 if (cTries++ == 10) 00290 return -1; 00291 00292 pPropSet = UserLocalAlloc(0, cPropSets * sizeof(PROPSET)); 00293 if (pPropSet == NULL) 00294 return -1; 00295 00296 Status = NtUserBuildPropList(hwnd, cPropSets, pPropSet, &cPropSets); 00297 } 00298 00299 if (!NT_SUCCESS(Status)) { 00300 UserLocalFree(pPropSet); 00301 return -1; 00302 } 00303 00304 for (ii=0; ii<cPropSets; ii++) { 00305 00306 if (ISSTRINGATOM(pPropSet[ii].atom)) { 00307 00308 pKey = (PVOID)awch; 00309 if (flags & IEP_UNICODE) 00310 cchName = GlobalGetAtomNameW(pPropSet[ii].atom, (LPWSTR)pKey, MAX_ATOM_SIZE); 00311 else 00312 cchName = GlobalGetAtomNameA(pPropSet[ii].atom, (LPSTR)pKey, sizeof(awch)); 00313 00314 /* 00315 * If cchName is zero, we must assume that the property belongs 00316 * to another process. Because we can't get the name, just skip 00317 * it. 00318 */ 00319 if (cchName == 0) 00320 continue; 00321 00322 } else { 00323 pKey = (PVOID)pPropSet[ii].atom; 00324 } 00325 00326 if (flags & IEP_ENUMEX) { 00327 iRetVal = (*(PROPENUMPROCEX)lpfn)(hwnd, pKey, 00328 pPropSet[ii].hData, lParam); 00329 } else { 00330 iRetVal = (*lpfn)(hwnd, pKey, pPropSet[ii].hData); 00331 } 00332 00333 if (!iRetVal) 00334 break; 00335 } 00336 00337 UserLocalFree(pPropSet); 00338 00339 return iRetVal; 00340 } 00341 00342 00343 /***************************************************************************\ 00344 * EnumProps 00345 * 00346 * This function enumerates all entries in the property list of the specified 00347 * window. It enumerates the entries by passing them, one by one, to the 00348 * callback function specified by lpEnumFunc. EnumProps continues until the 00349 * last entry is enumerated or the callback function return s zero. 00350 * 00351 * 22-Jan-1992 JohnC Created. 00352 \***************************************************************************/ 00353 00354 INT WINAPI EnumPropsA( 00355 HWND hwnd, 00356 PROPENUMPROCA lpfn) 00357 { 00358 return InternalEnumProps(hwnd, (PROPENUMPROC)lpfn, 0, 0); 00359 } 00360 00361 00362 INT WINAPI EnumPropsW( 00363 HWND hwnd, 00364 PROPENUMPROCW lpfn) 00365 { 00366 return InternalEnumProps(hwnd, (PROPENUMPROC)lpfn, 0, IEP_UNICODE); 00367 } 00368 00369 /***************************************************************************\ 00370 * EnumPropsEx 00371 * 00372 * This function enumerates all entries in the property list of the specified 00373 * window. It enumerates the entries by passing them, one by one, to the 00374 * callback function specified by lpEnumFunc. EnumProps continues until the 00375 * last entry is enumerated or the callback function return s zero. 00376 * 00377 * 22-Jan-1992 JohnC Created. 00378 \***************************************************************************/ 00379 00380 BOOL WINAPI EnumPropsExA( 00381 HWND hwnd, 00382 PROPENUMPROCEXA lpfn, 00383 LPARAM lParam) 00384 { 00385 return InternalEnumProps(hwnd, (PROPENUMPROC)lpfn, lParam, IEP_ENUMEX); 00386 } 00387 00388 BOOL WINAPI EnumPropsExW( 00389 HWND hwnd, 00390 PROPENUMPROCEXW lpfn, 00391 LPARAM lParam) 00392 { 00393 return InternalEnumProps(hwnd, (PROPENUMPROC)lpfn, lParam, IEP_UNICODE|IEP_ENUMEX); 00394 } 00395 00396 00397 00398 BOOL InternalEnumObjects( 00399 HWINSTA hwinsta, 00400 NAMEENUMPROCW lpfn, 00401 LPARAM lParam, 00402 BOOL fAnsi) 00403 { 00404 PNAMELIST pNameList; 00405 DWORD i; 00406 UINT cbData; 00407 PWCHAR pwch; 00408 PCHAR pch; 00409 CHAR achTmp[MAX_PATH]; 00410 BOOL iRetVal; 00411 NTSTATUS Status; 00412 int cTries; 00413 00414 /* 00415 * Allocate a buffer to hold the names. 00416 */ 00417 cbData = 256; 00418 pNameList = UserLocalAlloc(0, cbData); 00419 if (pNameList == NULL) 00420 return FALSE; 00421 00422 Status = NtUserBuildNameList(hwinsta, cbData, pNameList, &cbData); 00423 00424 /* 00425 * If the buffer wasn't big enough, reallocate 00426 * the buffer and try again. 00427 */ 00428 cTries = 0; 00429 while (Status == STATUS_BUFFER_TOO_SMALL) { 00430 UserLocalFree(pNameList); 00431 00432 /* 00433 * If we can't seem to get it right, 00434 * call it quits 00435 */ 00436 if (cTries++ == 10) 00437 break; 00438 00439 pNameList = UserLocalAlloc(0, cbData); 00440 if (pNameList == NULL) 00441 break; 00442 00443 Status = NtUserBuildNameList(hwinsta, cbData, pNameList, &cbData); 00444 } 00445 00446 if (!NT_SUCCESS(Status)) { 00447 UserLocalFree(pNameList); 00448 return FALSE; 00449 } 00450 00451 pwch = pNameList->awchNames; 00452 pch = achTmp; 00453 00454 for (i = 0; i < pNameList->cNames; i++) { 00455 if (fAnsi) { 00456 if (WCSToMB(pwch, -1, &pch, sizeof(achTmp), FALSE) == 00457 sizeof(achTmp)) { 00458 00459 /* 00460 * The buffer may have overflowed, so force it to be 00461 * allocated. 00462 */ 00463 if (WCSToMB(pwch, -1, &pch, -1, TRUE) == 0) { 00464 iRetVal = FALSE; 00465 break; 00466 } 00467 } 00468 iRetVal = (*(NAMEENUMPROCA)lpfn)(pch, lParam); 00469 if (pch != achTmp) { 00470 UserLocalFree(pch); 00471 pch = achTmp; 00472 } 00473 } else { 00474 iRetVal = (*(NAMEENUMPROCW)lpfn)(pwch, lParam); 00475 } 00476 if (!iRetVal) 00477 break; 00478 00479 pwch = pwch + wcslen(pwch) + 1; 00480 } 00481 00482 UserLocalFree(pNameList); 00483 00484 return iRetVal; 00485 } 00486 00487 BOOL WINAPI EnumWindowStationsA( 00488 WINSTAENUMPROCA lpEnumFunc, 00489 LPARAM lParam) 00490 { 00491 return InternalEnumObjects(NULL, (NAMEENUMPROCW)lpEnumFunc, lParam, TRUE); 00492 } 00493 00494 BOOL WINAPI EnumWindowStationsW( 00495 WINSTAENUMPROCW lpEnumFunc, 00496 LPARAM lParam) 00497 { 00498 return InternalEnumObjects(NULL, (NAMEENUMPROCW)lpEnumFunc, lParam, FALSE); 00499 } 00500 00501 00502 BOOL WINAPI EnumDesktopsA( 00503 HWINSTA hwinsta, 00504 DESKTOPENUMPROCA lpEnumFunc, 00505 LPARAM lParam) 00506 { 00507 return InternalEnumObjects(hwinsta, (NAMEENUMPROCW)lpEnumFunc, lParam, TRUE); 00508 } 00509 00510 BOOL WINAPI EnumDesktopsW( 00511 HWINSTA hwinsta, 00512 DESKTOPENUMPROCW lpEnumFunc, 00513 LPARAM lParam) 00514 { 00515 return InternalEnumObjects(hwinsta, (NAMEENUMPROCW)lpEnumFunc, lParam, FALSE); 00516 }

Generated on Sat May 15 19:39:24 2004 for test by doxygen 1.3.7