00001
00002
00003
00004
00005
00006
00007
00008
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
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
00065
00066
00067 cTries = 0;
00068
while (
Status == STATUS_BUFFER_TOO_SMALL) {
00069
UserLocalFree(phwndFirst);
00070
00071
00072
00073
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
00111
00112
00113
if ((cHwnd =
BuildHwndList(hdesk, hwnd, fEnumChildren, idThread,
00114 &phwndFirst)) == -1) {
00115
return FALSE;
00116 }
00117
00118
00119
00120
00121
if (cHwnd == 0) {
00122
if (idThread == 0)
00123
return FALSE;
00124
else
00125
return TRUE;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134 phwndT = phwndFirst;
00135
for (i = 0; i < cHwnd; i++) {
00136
00137
00138
00139
00140
00141
00142
if (
ValidateHwnd(*phwndT)) {
00143
if (!(fSuccess = (*lpfn)(*phwndT, lParam)))
00144
break;
00145 }
00146 phwndT++;
00147 }
00148
00149
00150
00151
00152
00153 phwndT = (HWND *)InterlockedExchangePointer(&(PVOID)
phwndCache, phwndFirst);
00154
if (phwndT !=
NULL) {
00155
UserLocalFree(phwndT);
00156 }
00157
return fSuccess;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 BOOL WINAPI
EnumWindows(
00172 WNDENUMPROC lpfn,
00173 LPARAM lParam)
00174 {
00175
return InternalEnumWindows(
NULL,
NULL, lpfn, lParam, 0
L,
FALSE);
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 BOOL WINAPI
EnumChildWindows(
00189 HWND hwnd,
00190 WNDENUMPROC lpfn,
00191 LPARAM lParam)
00192 {
00193
return InternalEnumWindows(
NULL, hwnd, lpfn, lParam, 0
L,
TRUE);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
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
00216
00217
00218
00219
00220
00221
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
00237
00238
00239
00240
00241
00242
00243
00244
00245
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
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
00279
00280
00281 cTries = 0;
00282
while (
Status == STATUS_BUFFER_TOO_SMALL) {
00283
UserLocalFree(pPropSet);
00284
00285
00286
00287
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
00316
00317
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
00345
00346
00347
00348
00349
00350
00351
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
00371
00372
00373
00374
00375
00376
00377
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
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
00426
00427
00428 cTries = 0;
00429
while (
Status == STATUS_BUFFER_TOO_SMALL) {
00430
UserLocalFree(pNameList);
00431
00432
00433
00434
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
00461
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 }