00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include "precomp.h"
00016
#pragma hdrstop
00017
00018
#undef DUMMY_TEXT_HANDLE
00019 #define DUMMY_TEXT_HANDLE (HANDLE)0x0001 // must be first dummy
00020 #define DUMMY_DIB_HANDLE (HANDLE)0x0002
00021 #define DUMMY_METARENDER_HANDLE (HANDLE)0x0003
00022 #define DUMMY_METACLONE_HANDLE (HANDLE)0x0004
00023 #define DUMMY_MAX_HANDLE (HANDLE)0x0004 // must be last dummy
00024
00025 #define PRIVATEFORMAT 0
00026 #define GDIFORMAT 1
00027 #define HANDLEFORMAT 2
00028 #define METAFILEFORMAT 3
00029
00030 #define IsTextHandle(fmt, hdata) \
00031
(((hdata) != DUMMY_TEXT_HANDLE) && \
00032
(((fmt) == CF_TEXT) || ((fmt) == CF_OEMTEXT) || ((fmt) == CF_UNICODETEXT)))
00033
00034 #define IsDibHandle(fmt, hdata) \
00035
(((fmt) == CF_DIB) && ((hdata) != DUMMY_DIB_HANDLE))
00036 #define IsMetaDummyHandle(hdata) \
00037
((hdata == DUMMY_METACLONE_HANDLE) || (hdata == DUMMY_METARENDER_HANDLE))
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 PWINDOWSTATION CheckClipboardAccess(
void)
00050 {
00051
NTSTATUS Status;
00052
PWINDOWSTATION pwinsta;
00053
BOOL fUseDesktop;
00054
PTHREADINFO pti;
00055
00056 pti =
PtiCurrentShared();
00057
00058
00059
00060
00061
00062
00063 fUseDesktop = (pti->
TIF_flags &
TIF_CSRSSTHREAD) ?
TRUE :
FALSE;
00064
00065
Status =
ReferenceWindowStation(
PsGetCurrentThread(),
00066
NULL,
00067 WINSTA_ACCESSCLIPBOARD,
00068 &pwinsta,
00069 fUseDesktop);
00070
if (!
NT_SUCCESS(
Status)) {
00071 RIPNTERR0(
Status, RIP_WARNING,
"Access to clipboard denied.");
00072
return NULL;
00073 }
00074
00075
return pwinsta;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 HANDLE
_ConvertMemHandle(
00089 LPBYTE ccxlpData,
00090
int cbData)
00091 {
00092
PCLIPDATA pClipData;
00093
00094 pClipData =
HMAllocObject(
NULL,
00095
NULL,
00096
TYPE_CLIPDATA,
00097 FIELD_OFFSET(
CLIPDATA, abData) + cbData);
00098
00099
if (pClipData ==
NULL)
00100
return NULL;
00101
00102 pClipData->
cbData = cbData;
00103
00104
try {
00105 RtlCopyMemory(&pClipData->
abData, ccxlpData, cbData);
00106 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00107
HMFreeObject(pClipData);
00108
return NULL;
00109 }
00110
00111
return PtoHq(pClipData);
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 BOOL xxxOpenClipboard(
00125
PWND pwnd,
00126 LPBOOL lpfEmptyClient)
00127 {
00128
PTHREADINFO pti;
00129
PWINDOWSTATION pwinsta;
00130
00131
CheckLock(pwnd);
00132
00133
if (lpfEmptyClient !=
NULL)
00134 *lpfEmptyClient =
FALSE;
00135
00136
00137
00138
00139
if ((pwinsta =
CheckClipboardAccess()) ==
NULL)
00140
return FALSE;
00141
00142 pti =
PtiCurrent();
00143
00144
00145
00146
00147
00148
if ((pwnd == pwinsta->
spwndClipOpen) && (pti == pwinsta->
ptiClipLock))
00149
return TRUE;
00150
00151
if ((pwnd != pwinsta->
spwndClipOpen) && (pwinsta->
ptiClipLock !=
NULL)) {
00152
00153
#if DBG
00154
00155
00156
00157
00158
if (pti != pwinsta->
ptiClipLock) {
00159
00160 RIPMSG0(RIP_VERBOSE,
00161
"Clipboard: OpenClipboard already out by another thread");
00162 }
00163
#endif
00164
return FALSE;
00165 }
00166
00167
00168
00169
00170
00171
00172 UserAssert((pwnd ==
NULL ) || (!
TestWF(pwnd,
WFDESTROYED)));
00173
00174
Lock(&pwinsta->
spwndClipOpen, pwnd);
00175 pwinsta->
ptiClipLock = pti;
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
if (lpfEmptyClient !=
NULL) {
00196
00197
if (!(pti->
TIF_flags &
TIF_16BIT) ||
00198 (pti->
ppi->
iClipSerialNumber != pwinsta->
iClipSerialNumber)) {
00199
00200 *lpfEmptyClient = (pwinsta->
spwndClipOwner ==
NULL) ||
00201 (pwinsta->
ptiClipLock->
ppi !=
00202
GETPTI(pwinsta->
spwndClipOwner)->ppi);
00203
00204 pti->
ppi->
iClipSerialNumber = pwinsta->
iClipSerialNumber;
00205 }
00206 }
00207
00208
return TRUE;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 VOID xxxDrawClipboard(
00221
PWINDOWSTATION pwinsta)
00222 {
00223
00224
00225
00226
00227 pwinsta->
fClipboardChanged =
FALSE;
00228
00229
if (pwinsta->
ptiDrawingClipboard ==
NULL && pwinsta->
spwndClipViewer !=
NULL) {
00230
00231
TL tlpwndClipViewer;
00232
00233
00234
00235
00236
00237
00238 pwinsta->
ptiDrawingClipboard =
PtiCurrent();
00239
ThreadLockAlways(pwinsta->
spwndClipViewer, &tlpwndClipViewer);
00240
00241
if (!(
PtiCurrent()->TIF_flags &
TIF_16BIT)) {
00242
00243
00244
00245
xxxSendNotifyMessage(pwinsta->
spwndClipViewer,
00246 WM_DRAWCLIPBOARD,
00247 (WPARAM)
HW(pwinsta->
spwndClipOwner),
00248 0
L);
00249 }
else {
00250
xxxSendMessage(pwinsta->
spwndClipViewer,
00251 WM_DRAWCLIPBOARD,
00252 (WPARAM)
HW(pwinsta->
spwndClipOwner),
00253 0
L);
00254 }
00255
00256
ThreadUnlock(&tlpwndClipViewer);
00257 pwinsta->
ptiDrawingClipboard =
NULL;
00258 }
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 VOID PasteScreenPalette(
00271
PWINDOWSTATION pwinsta)
00272 {
00273
int irgb;
00274
int crgbPal;
00275 LPLOGPALETTE lppal;
00276 HPALETTE hpal =
NULL;
00277
int crgbFixed;
00278
00279 UserAssert(
TEST_PUSIF(
PUSIF_PALETTEDISPLAY));
00280
00281
00282
00283
00284 crgbPal = GreGetDeviceCaps(
gpDispInfo->
hdcScreen, SIZEPALETTE);
00285
00286
if (GreGetSystemPaletteUse(
gpDispInfo->
hdcScreen) == SYSPAL_STATIC) {
00287 crgbFixed = GreGetDeviceCaps(
gpDispInfo->
hdcScreen, NUMRESERVED) / 2;
00288 }
else {
00289 crgbFixed = 1;
00290 }
00291
00292 lppal = (LPLOGPALETTE)UserAllocPool(
sizeof(LOGPALETTE) +
00293 (
sizeof(PALETTEENTRY) * crgbPal),
00294 TAG_CLIPBOARD);
00295
00296
if (lppal ==
NULL)
00297
return;
00298
00299 lppal->palVersion = 0x300;
00300 lppal->palNumEntries = (WORD)crgbPal;
00301
00302
if (GreGetSystemPaletteEntries(
gpDispInfo->
hdcScreen, 0, crgbPal, lppal->palPalEntry)) {
00303
00304 crgbPal -= crgbFixed;
00305
00306
for (irgb = crgbFixed; irgb < crgbPal; irgb++) {
00307
00308
00309
00310
00311
00312 lppal->palPalEntry[irgb].peFlags = PC_NOCOLLAPSE;
00313 }
00314
00315 hpal = GreCreatePalette(lppal);
00316 }
00317
00318 UserFreePool((HANDLE)lppal);
00319
00320
if (hpal) {
00321
InternalSetClipboardData(pwinsta, CF_PALETTE, hpal,
FALSE,
TRUE);
00322 GreSetPaletteOwner(hpal, OBJECT_OWNER_PUBLIC);
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 VOID MungeClipData(
00336
PWINDOWSTATION pwinsta)
00337 {
00338
PCLIP pOEM;
00339
PCLIP pTXT;
00340
PCLIP pUNI;
00341
PCLIP pBMP;
00342
PCLIP pDIB;
00343
PCLIP pDV5;
00344
00345
PCLIP pClip;
00346
00347
00348
00349
00350
00351 pTXT =
FindClipFormat(pwinsta, CF_TEXT);
00352 pOEM =
FindClipFormat(pwinsta, CF_OEMTEXT);
00353 pUNI =
FindClipFormat(pwinsta, CF_UNICODETEXT);
00354
00355
if (pTXT !=
NULL || pOEM !=
NULL || pUNI !=
NULL) {
00356
00357
00358
00359
00360
if (!
FindClipFormat(pwinsta, CF_LOCALE)) {
00361
00362
00363
00364
00365
00366
PTHREADINFO ptiCurrent =
PtiCurrent();
00367
DWORD lcid;
00368
DWORD lang;
00369 HANDLE hLocale;
00370
00371
00372
00373
00374
00375
00376
00377
if (ptiCurrent->
spklActive) {
00378 lang = HandleToUlong(ptiCurrent->
spklActive->
hkl);
00379
00380 lcid = MAKELCID(LOWORD(lang), SORT_DEFAULT);
00381
00382
if (hLocale =
_ConvertMemHandle((LPBYTE)&lcid,
sizeof(
DWORD))) {
00383
if (!
InternalSetClipboardData(pwinsta,
00384 CF_LOCALE,
00385 hLocale,
00386
FALSE,
00387
TRUE)) {
00388 PVOID pObj;
00389
00390 pObj =
HMValidateHandleNoRip(hLocale,
TYPE_CLIPDATA);
00391
if (pObj !=
NULL) {
00392
HMFreeObject(pObj);
00393 }
00394 }
00395 }
00396 }
00397 }
00398
00399
if (pTXT ==
NULL)
00400
InternalSetClipboardData(pwinsta,
00401 CF_TEXT,
00402 (HANDLE)
DUMMY_TEXT_HANDLE,
00403
FALSE,
00404
TRUE);
00405
00406
if (pOEM ==
NULL)
00407
InternalSetClipboardData(pwinsta,
00408 CF_OEMTEXT,
00409 (HANDLE)
DUMMY_TEXT_HANDLE,
00410
FALSE,
00411
TRUE);
00412
00413
if (pUNI ==
NULL)
00414
InternalSetClipboardData(pwinsta,
00415 CF_UNICODETEXT,
00416 (HANDLE)
DUMMY_TEXT_HANDLE,
00417
FALSE,
00418
TRUE);
00419 }
00420
00421
00422
00423
00424
00425
00426
if (!
FindClipFormat(pwinsta, CF_METAFILEPICT) &&
00427 (pClip =
FindClipFormat(pwinsta, CF_ENHMETAFILE))) {
00428
00429
InternalSetClipboardData(pwinsta,
00430 CF_METAFILEPICT,
00431 pClip->
hData ?
DUMMY_METACLONE_HANDLE :
00432
DUMMY_METARENDER_HANDLE,
00433
FALSE,
00434
TRUE);
00435
00436 }
else if (!
FindClipFormat(pwinsta, CF_ENHMETAFILE) &&
00437 (pClip =
FindClipFormat(pwinsta, CF_METAFILEPICT))) {
00438
00439
InternalSetClipboardData(pwinsta,
00440 CF_ENHMETAFILE,
00441 pClip->
hData ?
DUMMY_METACLONE_HANDLE :
00442
DUMMY_METARENDER_HANDLE,
00443
FALSE,
00444
TRUE);
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454 pBMP =
FindClipFormat(pwinsta, CF_BITMAP);
00455 pDIB =
FindClipFormat(pwinsta, CF_DIB);
00456 pDV5 =
FindClipFormat(pwinsta, CF_DIBV5);
00457
00458
if (pBMP !=
NULL || pDIB !=
NULL || pDV5 !=
NULL) {
00459
00460
00461
00462
00463
if (pBMP ==
NULL) {
00464
InternalSetClipboardData(pwinsta,
00465 CF_BITMAP,
00466
DUMMY_DIB_HANDLE,
00467
FALSE,
00468
TRUE);
00469 }
00470
00471
00472
00473
00474
if (pDIB ==
NULL) {
00475
InternalSetClipboardData(pwinsta,
00476 CF_DIB,
00477
DUMMY_DIB_HANDLE,
00478
FALSE,
00479
TRUE);
00480 }
00481
00482
00483
00484
00485
if (pDV5 ==
NULL) {
00486
InternalSetClipboardData(pwinsta,
00487 CF_DIBV5,
00488
DUMMY_DIB_HANDLE,
00489
FALSE,
00490
TRUE);
00491 }
00492
00493
if (
TEST_PUSIF(
PUSIF_PALETTEDISPLAY) &&
00494 !
FindClipFormat(pwinsta, CF_PALETTE)) {
00495
00496
00497
00498
00499
if (pDIB !=
NULL || pDV5 !=
NULL)
00500 {
00501
00502
00503
00504
InternalSetClipboardData(pwinsta,
00505 CF_PALETTE,
00506
DUMMY_DIB_HANDLE,
00507
FALSE,
00508
TRUE);
00509 }
else {
00510
00511
00512
00513
PasteScreenPalette(pwinsta);
00514 }
00515 }
00516 }
00517
00518
return;
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 BOOL xxxCloseClipboard(
00539
PWINDOWSTATION pwinsta)
00540 {
00541
PTHREADINFO ptiCurrent;
00542
TL tlpwinsta;
00543
00544
if ((pwinsta ==
NULL) && ((pwinsta =
CheckClipboardAccess()) ==
NULL)) {
00545
return FALSE;
00546 }
00547
00548
00549
00550
00551
00552 ptiCurrent =
PtiCurrent();
00553
00554
if (pwinsta->
ptiClipLock != ptiCurrent) {
00555 RIPERR0(ERROR_CLIPBOARD_NOT_OPEN, RIP_WARNING,
"xxxCloseClipboard not open");
00556
return FALSE;
00557 }
00558
00559
ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);
00560
00561
00562
00563
00564
if (pwinsta->
fClipboardChanged)
00565
MungeClipData(pwinsta);
00566
00567
00568
00569
00570
00571
Unlock(&pwinsta->
spwndClipOpen);
00572 pwinsta->
ptiClipLock =
NULL;
00573
00574
00575
00576
00577
00578
if (pwinsta->
fClipboardChanged)
00579
xxxDrawClipboard(pwinsta);
00580
00581
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
00582
00583
return TRUE;
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 UINT _EnumClipboardFormats(
00598 UINT fmt)
00599 {
00600
PWINDOWSTATION pwinsta;
00601
UINT fmtRet;
00602
00603
if ((pwinsta =
CheckClipboardAccess()) ==
NULL)
00604
return 0;
00605
00606
00607
00608
00609
00610
if (pwinsta->
ptiClipLock !=
PtiCurrent()) {
00611 RIPERR0(ERROR_CLIPBOARD_NOT_OPEN, RIP_WARNING,
"EnumClipboardFormat: clipboard not open");
00612
return 0;
00613 }
00614
00615 fmtRet = 0;
00616
00617
if (pwinsta->
pClipBase !=
NULL) {
00618
00619
PCLIP pClip;
00620
00621
00622
00623
00624
00625
if (fmt != 0) {
00626
00627
00628
00629
00630
00631
00632
if ((pClip =
FindClipFormat(pwinsta, fmt)) !=
NULL)
00633 pClip++;
00634
00635 }
else {
00636 pClip = pwinsta->
pClipBase;
00637 }
00638
00639
00640
00641
00642
if (pClip && (pClip < &pwinsta->
pClipBase[pwinsta->
cNumClipFormats])) {
00643
00644 fmtRet = pClip->
fmt;
00645 }
00646 }
00647
00648
00649
00650
00651
return fmtRet;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 int UT_GetFormatType(
00669
PCLIP pClip)
00670 {
00671
switch (pClip->
fmt) {
00672
00673
case CF_BITMAP:
00674
case CF_DSPBITMAP:
00675
case CF_PALETTE:
00676
return GDIFORMAT;
00677
00678
case CF_METAFILEPICT:
00679
case CF_DSPMETAFILEPICT:
00680
case CF_ENHMETAFILE:
00681
case CF_DSPENHMETAFILE:
00682
return METAFILEFORMAT;
00683
00684
case CF_OWNERDISPLAY:
00685
return PRIVATEFORMAT;
00686
00687
default:
00688
return HANDLEFORMAT;
00689 }
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 VOID UT_FreeCBFormat(
00702
PCLIP pClip)
00703 {
00704 PVOID pObj;
00705
00706
00707
00708
00709
if (pClip->
hData ==
NULL)
00710
return;
00711
00712
00713
00714
00715
switch (
UT_GetFormatType(pClip)) {
00716
00717
case METAFILEFORMAT:
00718
00719
00720
00721
00722
00723
if (!
IsMetaDummyHandle(pClip->
hData)) {
00724 GreDeleteServerMetaFile(pClip->
hData);
00725 }
00726
break;
00727
00728
case HANDLEFORMAT:
00729
00730
00731
00732
00733
00734
00735
00736
00737
if ((pClip->
hData !=
DUMMY_TEXT_HANDLE) &&
00738 (pClip->
hData !=
DUMMY_DIB_HANDLE)) {
00739
00740 pObj =
HMValidateHandleNoRip(pClip->
hData,
TYPE_CLIPDATA);
00741
if (pObj) {
00742
HMFreeObject(pObj);
00743 }
00744 }
00745
break;
00746
00747
case GDIFORMAT:
00748
00749
00750
00751
00752
if (pClip->
hData !=
DUMMY_DIB_HANDLE) {
00753 GreDeleteObject(pClip->
hData);
00754 }
00755
break;
00756
00757
case PRIVATEFORMAT:
00758
00759
00760
00761
00762
00763
00764
if (pClip->
fGlobalHandle) {
00765 pObj =
HMValidateHandleNoRip(pClip->
hData,
TYPE_CLIPDATA);
00766
if (pObj) {
00767
HMFreeObject(pObj);
00768 }
00769 }
00770
break;
00771 }
00772 }
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 VOID xxxSendClipboardMessage(
00784
PWINDOWSTATION pwinsta,
00785 UINT message)
00786 {
00787
TL tlpwndClipOwner;
00788 LONG_PTR dwResult;
00789 LRESULT lRet;
00790
00791
if (pwinsta->
spwndClipOwner !=
NULL) {
00792
00793
PWND pwndClipOwner = pwinsta->
spwndClipOwner;
00794
00795
ThreadLockAlways(pwndClipOwner, &tlpwndClipOwner);
00796
00797
00798
00799
00800
00801
00802
00803
00804
if ((message == WM_DESTROYCLIPBOARD) &&
00805 !(
PtiCurrent()->TIF_flags &
TIF_16BIT)) {
00806
00807
00808
00809
00810
00811
00812 lRet =
xxxSendMessageTimeout(
00813 pwndClipOwner,
00814 WM_DESTROYCLIPBOARD,
00815 0,
00816 0
L,
00817 SMTO_ABORTIFHUNG | SMTO_NORMAL,
00818 5 * 1000,
00819 &dwResult);
00820
00821
if (lRet == 0) {
00822
00823
00824
00825
00826
00827 RIPMSG0(RIP_WARNING,
"Sending WM_DESTROYCLIPBOARD timed-out, resending via SendNotifyMessage");
00828
xxxSendNotifyMessage(pwndClipOwner, WM_DESTROYCLIPBOARD, 0, 0
L);
00829 }
00830
00831 }
else {
00832
00833
xxxSendMessage(pwndClipOwner, message, 0, 0
L);
00834 }
00835
00836
ThreadUnlock(&tlpwndClipOwner);
00837 }
00838
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 BOOL xxxEmptyClipboard(
00852
PWINDOWSTATION pwinsta)
00853 {
00854
TL tlpwinsta;
00855
PCLIP pClip;
00856
int cFmts;
00857
BOOL fDying;
00858
PTHREADINFO ptiCurrent = (
PTHREADINFO)(W32GetCurrentThread());
00859
BOOL bInternal = !(pwinsta ==
NULL);
00860
00861
00862
00863
00864
if ((pwinsta ==
NULL) && ((pwinsta =
CheckClipboardAccess()) ==
NULL))
00865
return FALSE;
00866
00867
00868
00869
00870
00871
00872
if (ptiCurrent ==
NULL) {
00873 UserAssert(bInternal);
00874 }
00875
00876
if (!bInternal) {
00877
if (pwinsta->
ptiClipLock != ptiCurrent) {
00878 RIPERR0(ERROR_CLIPBOARD_NOT_OPEN, RIP_WARNING,
"xxxEmptyClipboard: clipboard not open");
00879
return FALSE;
00880 }
00881 }
00882
00883
00884
00885
00886 fDying = pwinsta->
dwWSF_Flags &
WSF_DYING;
00887
00888
if (!fDying && ptiCurrent) {
00889
ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);
00890
00891
00892
00893
00894
00895
xxxSendClipboardMessage(pwinsta, WM_DESTROYCLIPBOARD);
00896 }
00897
00898
if ((pClip = pwinsta->
pClipBase) !=
NULL) {
00899
00900
00901
00902
00903
00904
for (cFmts = pwinsta->
cNumClipFormats; cFmts-- != 0;) {
00905
00906
if ((ATOM)pClip->
fmt >= MAXINTATOM)
00907
UserDeleteAtom((ATOM)pClip->
fmt);
00908
00909
UT_FreeCBFormat(pClip++);
00910 }
00911
00912
00913
00914
00915 UserFreePool((HANDLE)pwinsta->
pClipBase);
00916 pwinsta->
pClipBase =
NULL;
00917 pwinsta->
cNumClipFormats = 0;
00918 }
00919
00920
00921
00922
00923
00924
00925 pwinsta->
fClipboardChanged =
TRUE;
00926
Lock(&pwinsta->
spwndClipOwner, pwinsta->
spwndClipOpen);
00927
00928
00929
00930
00931
00932
00933 pwinsta->
iClipSerialNumber++;
00934 pwinsta->
iClipSequenceNumber++;
00935 pwinsta->
fInDelayedRendering =
FALSE;
00936
00937
if (!fDying && ptiCurrent)
00938
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
00939
00940
return TRUE;
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953 BOOL _SetClipboardData(
00954 UINT fmt,
00955 HANDLE hData,
00956 BOOL fGlobalHandle,
00957 BOOL fIncSerialNumber)
00958 {
00959
PWINDOWSTATION pwinsta;
00960
BOOL fRet;
00961
00962
if ((pwinsta =
CheckClipboardAccess()) ==
NULL)
00963
return FALSE;
00964
00965
00966
00967
00968
00969
00970
00971
if ((hData >=
DUMMY_TEXT_HANDLE) && (hData <=
DUMMY_MAX_HANDLE)) {
00972 RIPMSG0(RIP_WARNING,
"Clipboard: SetClipboardData called with dummy-handle");
00973
return FALSE;
00974 }
00975
00976
if (fRet =
InternalSetClipboardData(pwinsta, fmt, hData, fGlobalHandle, fIncSerialNumber)) {
00977
00978
00979
00980
00981
00982
switch (fmt) {
00983
case CF_BITMAP:
00984 GreSetBitmapOwner(hData, OBJECT_OWNER_PUBLIC);
00985
break;
00986
00987
case CF_PALETTE:
00988 GreSetPaletteOwner(hData, OBJECT_OWNER_PUBLIC);
00989
break;
00990 }
00991 }
00992
00993
return fRet;
00994 }
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005 #define CCHFORMATNAME 256
01006
01007 BOOL InternalSetClipboardData(
01008
PWINDOWSTATION pwinsta,
01009 UINT fmt,
01010 HANDLE hData,
01011 BOOL fGlobalHandle,
01012 BOOL fIncSerialNumber)
01013 {
01014
PCLIP pClip;
01015 WCHAR achFormatName[
CCHFORMATNAME];
01016
01017
01018
01019
01020
01021
01022
if ((pwinsta->
ptiClipLock ==
NULL) || (fmt == 0)) {
01023 RIPERR0(ERROR_CLIPBOARD_NOT_OPEN, RIP_WARNING,
"SetClipboardData: Clipboard not open");
01024
return FALSE;
01025 }
01026
01027
if ((pClip =
FindClipFormat(pwinsta, fmt)) !=
NULL) {
01028
01029
01030
01031
01032
UT_FreeCBFormat(pClip);
01033
01034 }
else {
01035
01036
if (pwinsta->
pClipBase ==
NULL) {
01037 pClip = (
PCLIP)UserAllocPool(
sizeof(
CLIP), TAG_CLIPBOARD);
01038 }
else {
01039
DWORD dwSize =
sizeof(
CLIP) * pwinsta->
cNumClipFormats;
01040
01041 pClip = (
PCLIP)UserReAllocPool(pwinsta->
pClipBase,
01042 dwSize,
01043 dwSize +
sizeof(
CLIP),
01044 TAG_CLIPBOARD);
01045 }
01046
01047
01048
01049
01050
if (pClip ==
NULL) {
01051 RIPMSG0(RIP_WARNING,
"SetClipboardData: Out of memory");
01052
return FALSE;
01053 }
01054
01055
01056
01057
01058 pwinsta->
pClipBase = pClip;
01059
01060
01061
01062
01063
01064
01065
01066
01067
if (
UserGetAtomName((ATOM)fmt, achFormatName,
CCHFORMATNAME) != 0)
01068
UserAddAtom(achFormatName,
FALSE);
01069
01070
01071
01072
01073 pClip += pwinsta->
cNumClipFormats++;
01074 pClip->
fmt = fmt;
01075 }
01076
01077
01078
01079
01080 pClip->
hData = hData;
01081 pClip->
fGlobalHandle = fGlobalHandle;
01082
01083
if (fIncSerialNumber)
01084 pwinsta->
fClipboardChanged =
TRUE;
01085
01086
if (fIncSerialNumber && !pwinsta->
fInDelayedRendering) {
01087 pwinsta->
iClipSequenceNumber++;
01088 }
01089
01090
01091
01092
01093
01094
01095
01096
if ((pwinsta->
spwndClipOwner ==
NULL) ||
01097 (
GETPTI(pwinsta->
spwndClipOwner) !=
PtiCurrent())) {
01098
01099 RIPMSG0(RIP_VERBOSE,
"Clipboard: SetClipboardData called without emptying clipboard");
01100
01101
if (fIncSerialNumber)
01102 pwinsta->
iClipSerialNumber++;
01103 }
01104
01105
return TRUE;
01106 }
01107
01108
01109
01110
01111
01112
01113
01114 HBITMAP
CreateScreenBitmap(
01115
int cx,
01116
int cy,
01117 UINT bpp)
01118 {
01119
if (bpp == 1)
01120
return GreCreateBitmap(cx,
cy, 1, 1,
NULL);
01121
01122
return GreCreateCompatibleBitmap(
gpDispInfo->
hdcScreen, cx,
cy);
01123 }
01124
01125
01126
01127
01128
01129
01130
01131
01132 DWORD SizeOfDib(
01133 LPBITMAPINFOHEADER lpDib)
01134 {
01135
DWORD dwColor;
01136
DWORD dwBits;
01137
01138
01139
01140
01141 dwBits =
WIDTHBYTES(lpDib->biWidth * lpDib->biBitCount) *
abs(lpDib->biHeight);
01142
01143
01144
01145
01146
if ((lpDib->biCompression == BI_RGB) ||
01147 (lpDib->biCompression == BI_BITFIELDS)) {
01148
01149
if (lpDib->biClrUsed) {
01150 dwColor = lpDib->biClrUsed *
sizeof(
DWORD);
01151 }
else {
01152
if (lpDib->biBitCount <= 8) {
01153 dwColor = (1 << lpDib->biBitCount) *
sizeof(RGBQUAD);
01154 }
else if ((lpDib->biBitCount == 16) || (lpDib->biBitCount == 32)) {
01155
if (lpDib->biCompression == BI_BITFIELDS) {
01156 dwColor = (3 *
sizeof(
DWORD));
01157 }
else {
01158 dwColor = 0;
01159 }
01160 }
else {
01161 dwColor = 0;
01162 }
01163 }
01164
01165 }
else if (lpDib->biCompression == BI_RLE4) {
01166
01167 dwColor = 16 *
sizeof(
DWORD);
01168
01169 }
else if (lpDib->biCompression == BI_RLE8) {
01170
01171 dwColor = 256 *
sizeof(
DWORD);
01172
01173 }
else {
01174
01175 dwColor = 0;
01176
01177 }
01178
01179
return (lpDib->biSize + dwColor + dwBits);
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189 HBITMAP
DIBtoBMP(
01190 LPBITMAPINFOHEADER lpbih,
01191 HPALETTE hpal)
01192 {
01193 HDC hdc;
01194
int cx;
01195
int cy;
01196
int bpp;
01197 LPSTR lpbits;
01198 HBITMAP hbmp;
01199
01200
#define lpbch ((LPBITMAPCOREHEADER)lpbih)
01201
01202
01203
01204
01205
if (lpbih->biSize ==
sizeof(BITMAPINFOHEADER)) {
01206
01207 cx = (
int)lpbih->biWidth;
01208
cy = (
int)lpbih->biHeight;
01209 bpp = (
int)lpbih->biBitCount;
01210
01211 lpbits = ((
PBYTE)lpbih) +
sizeof(BITMAPINFOHEADER);
01212
01213
if (lpbih->biClrUsed) {
01214 lpbits += (lpbih->biClrUsed *
sizeof(RGBQUAD));
01215 }
else if (bpp <= 8) {
01216 lpbits += ((1 << bpp) *
sizeof(RGBQUAD));
01217 }
else if ((bpp == 16) || (bpp == 32)) {
01218 lpbits += (3 *
sizeof(RGBQUAD));
01219 }
01220
01221 }
else if (
lpbch->bcSize ==
sizeof(BITMAPCOREHEADER)) {
01222
01223 cx = (
int)
lpbch->bcWidth;
01224
cy = (
int)
lpbch->bcHeight;
01225 bpp = (
int)
lpbch->bcBitCount;
01226
01227 lpbits = ((
PBYTE)
lpbch) +
sizeof(BITMAPCOREHEADER);
01228
01229
if (
lpbch->bcBitCount <= 8)
01230 lpbits += (1 << bpp);
01231
01232 }
else {
01233
return NULL;
01234 }
01235
01236 hbmp =
NULL;
01237
01238
if (hdc = GreCreateCompatibleDC(
gpDispInfo->
hdcScreen)) {
01239
01240
if (hbmp =
CreateScreenBitmap(cx,
cy, bpp)) {
01241
01242 HBITMAP hbmT;
01243 HPALETTE hpalT =
NULL;
01244
01245 hbmT = GreSelectBitmap(hdc, hbmp);
01246
01247
if (hpal) {
01248 hpalT =
_SelectPalette(hdc, hpal,
FALSE);
01249
xxxRealizePalette(hdc);
01250 }
01251
01252 GreSetDIBits(hdc,
01253 hbmp,
01254 0,
01255
cy,
01256 lpbits,
01257 (LPBITMAPINFO)lpbih,
01258 DIB_RGB_COLORS);
01259
01260
if (hpalT) {
01261
_SelectPalette(hdc, hpalT,
FALSE);
01262
xxxRealizePalette(hdc);
01263 }
01264
01265 GreSelectBitmap(hdc, hbmT);
01266 }
01267
01268 GreDeleteDC(hdc);
01269 }
01270
01271
#undef lpbch
01272
01273
return hbmp;
01274 }
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286 LPBITMAPINFOHEADER
BMPtoDIB(
01287 HBITMAP hbmp,
01288 HPALETTE hpal,
01289 DWORD* pcbSize)
01290 {
01291 BITMAP bmp;
01292 BITMAPINFOHEADER bi;
01293 LPBITMAPINFOHEADER lpbi;
01294
DWORD cbBits;
01295
DWORD cbPalette;
01296
DWORD cbTotal;
01297 WORD cBits;
01298 HDC hdc;
01299
01300 UserAssert(hbmp);
01301
01302
01303
01304
01305
if (!GreExtGetObjectW(hbmp,
sizeof(BITMAP), &bmp)) {
01306 UserAssert(
FALSE);
01307
return NULL;
01308 }
01309
01310
01311
01312
01313
01314 cBits = ((WORD)bmp.bmPlanes * (WORD)bmp.bmBitsPixel);
01315
01316
if (cBits <= 1) {
01317
01318 cBits = 1;
01319
01320 }
else if (cBits <= 4) {
01321
01322 cBits = 4;
01323
01324 }
else if (cBits <= 8) {
01325
01326 cBits = 8;
01327
01328 }
else {
01329
01330
01331
01332
01333
01334
01335
01336
01337
if (LOWORD(
PtiCurrent()->dwExpWinVer) >=
VER40) {
01338
01339
if (cBits <= 16)
01340 cBits = 16;
01341
else if (cBits <= 24)
01342 cBits = 24;
01343
else
01344 cBits = 32;
01345
01346 }
else {
01347 cBits = 24;
01348 }
01349 }
01350
01351
01352
01353
01354 RtlZeroMemory(&bi,
sizeof(bi));
01355
01356 bi.biSize =
sizeof(bi);
01357 bi.biWidth = bmp.bmWidth;
01358 bi.biHeight = bmp.bmHeight;
01359 bi.biPlanes = 1;
01360 bi.biBitCount = cBits;
01361 bi.biCompression = BI_RGB;
01362
01363
01364
01365
01366 cbBits = (
DWORD)
WIDTHBYTES((WORD)bi.biWidth * cBits) * (
DWORD)bi.biHeight;
01367
01368
01369
01370
01371 cbPalette = 0;
01372
01373
if (cBits <= 8) {
01374
01375 cbPalette = (1 << cBits) *
sizeof(RGBQUAD);
01376
01377 }
else if ((cBits == 16) || (cBits == 32)) {
01378
01379 cbPalette = (3 *
sizeof(
DWORD));
01380 bi.biCompression = BI_BITFIELDS;
01381 }
01382
01383
01384
01385
01386 cbTotal = bi.biSize + cbPalette + cbBits;
01387
01388 lpbi = (LPBITMAPINFOHEADER)UserAllocPool(cbTotal, TAG_CLIPBOARD);
01389
if (lpbi ==
NULL) {
01390
return NULL;
01391 }
01392
01393
01394
01395
01396
if (pcbSize !=
NULL) {
01397 *pcbSize = cbTotal;
01398 }
01399
01400
01401
01402
01403 memcpy(lpbi, &bi,
sizeof(bi));
01404
01405
if (hdc = GreCreateCompatibleDC(
gpDispInfo->
hdcScreen)) {
01406 HPALETTE hpalT =
NULL;
01407
TL tlPool;
01408
01409
ThreadLockPool(
PtiCurrent(), lpbi, &tlPool);
01410
01411
if (hpal) {
01412 hpalT =
_SelectPalette(hdc, hpal,
FALSE);
01413
xxxRealizePalette(hdc);
01414 }
01415
01416
01417
01418
01419
GreGetDIBitsInternal(hdc,
01420 hbmp,
01421 0,
01422 (WORD)bi.biHeight,
01423 (LPSTR)((LPSTR)lpbi + lpbi->biSize + cbPalette),
01424 (LPBITMAPINFO)lpbi,
01425 DIB_RGB_COLORS,
01426 cbBits,
01427 lpbi->biSize + cbPalette);
01428
01429
01430
if (hpalT) {
01431
_SelectPalette(hdc, hpalT,
FALSE);
01432
xxxRealizePalette(hdc);
01433 }
01434
01435 GreDeleteDC(hdc);
01436
01437
ThreadUnlockPool(
PtiCurrent(), &tlPool);
01438 }
01439
01440
return lpbi;
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450 LPBITMAPV5HEADER
DIBtoDIBV5(
01451 LPBITMAPINFOHEADER lpDib,
01452 DWORD cbSize)
01453 {
01454 LPBITMAPV5HEADER lpV5h;
01455 ULONG cjBits;
01456 ULONG cjColor, cjColorV5;
01457
BOOL bBitMasks =
FALSE;
01458
01459
if (cbSize <
sizeof(BITMAPINFOHEADER)) {
01460 RIPMSG2(RIP_WARNING,
"DIBtoDIBV5: buffer %d too small for header %d",
01461 cbSize,
sizeof(BITMAPINFOHEADER));
01462
return NULL;
01463 }
01464
01465
01466
01467
01468
if (lpDib->biSize !=
sizeof(BITMAPINFOHEADER))
01469
return NULL;
01470
01471
01472
01473
01474 cjBits =
WIDTHBYTES(lpDib->biWidth * lpDib->biBitCount) *
abs(lpDib->biHeight);
01475
01476
01477
01478
01479
if (lpDib->biCompression == BI_BITFIELDS) {
01480
01481
if ((lpDib->biBitCount == 16) || (lpDib->biBitCount == 32)) {
01482
01483
01484
01485 cjColor = (3 *
sizeof(
DWORD));
01486
01487
01488
01489
01490 cjColorV5 = 0;
01491 bBitMasks =
TRUE;
01492 }
else {
01493
01494
01495
01496 RIPMSG0(RIP_ERROR,
"Bad BITMAPINFOHEADER.");
01497 cjColor = cjColorV5 = 0;
01498 }
01499
01500 }
else if (lpDib->biCompression == BI_RGB) {
01501
01502
if (lpDib->biClrUsed) {
01503 cjColor = cjColorV5 = lpDib->biClrUsed *
sizeof(
DWORD);
01504 }
else {
01505
if (lpDib->biBitCount <= 8) {
01506 cjColor = cjColorV5 = (1 << lpDib->biBitCount) *
sizeof(RGBQUAD);
01507 }
else {
01508 cjColor = cjColorV5 = 0;
01509 }
01510 }
01511
01512 }
else if (lpDib->biCompression == BI_RLE4) {
01513
01514 cjColor = cjColorV5 = 16 *
sizeof(
DWORD);
01515
01516 }
else if (lpDib->biCompression == BI_RLE8) {
01517
01518 cjColor = cjColorV5 = 256 *
sizeof(
DWORD);
01519
01520 }
else {
01521
01522 cjColor = cjColorV5 = 0;
01523
01524 }
01525
01526
if (cbSize <
sizeof(BITMAPINFOHEADER) + cjColorV5 + cjBits) {
01527 RIPMSG5(RIP_WARNING,
"DIBtoDIBV5: buffer %d too small for bitmap %d Header"
01528
" %d cjColorV5 %d cjBits %d",
01529 cbSize,
01530
sizeof(BITMAPINFOHEADER) + cjColorV5 + cjBits,
01531
sizeof(BITMAPINFOHEADER),
01532 cjColorV5,
01533 cjBits);
01534
return NULL;
01535 }
01536
01537
01538
01539
01540 lpV5h = (LPBITMAPV5HEADER)UserAllocPool(
sizeof(BITMAPV5HEADER) + cjColorV5 + cjBits,
01541 TAG_CLIPBOARD);
01542
01543
if (lpV5h ==
NULL)
01544
return NULL;
01545
01546
01547
01548
01549 RtlZeroMemory((PVOID)lpV5h,
sizeof(BITMAPV5HEADER));
01550
01551
try {
01552
01553
01554
01555
01556 RtlCopyMemory((PVOID)lpV5h,(PVOID)lpDib,
sizeof(BITMAPINFOHEADER));
01557
01558 } except (W32ExceptionHandler(
FALSE, RIP_ERROR)) {
01559 UserFreePool(lpV5h);
01560
return NULL;
01561 }
01562
01563
01564
01565
01566 lpV5h->bV5Size =
sizeof(BITMAPV5HEADER);
01567
01568
01569
01570
01571 lpV5h->bV5CSType = LCS_sRGB;
01572
01573
01574
01575
01576 lpV5h->bV5Intent =
LCS_GM_IMAGES;
01577
01578
if (bBitMasks) {
01579
01580
01581
01582
01583 lpV5h->bV5RedMask = *(
DWORD *)&(((BITMAPINFO *)lpDib)->bmiColors[0]);
01584 lpV5h->bV5GreenMask = *(
DWORD *)&(((BITMAPINFO *)lpDib)->bmiColors[1]);
01585 lpV5h->bV5BlueMask = *(
DWORD *)&(((BITMAPINFO *)lpDib)->bmiColors[2]);
01586
01587 }
else {
01588
01589
01590
01591
01592
if (cjColorV5) {
01593 RtlCopyMemory((
BYTE *)lpV5h +
sizeof(BITMAPV5HEADER),
01594 (
BYTE *)lpDib +
sizeof(BITMAPINFOHEADER),
01595 cjColorV5);
01596 }
01597 }
01598
01599
01600
01601
01602 RtlCopyMemory((
BYTE *)lpV5h +
sizeof(BITMAPV5HEADER) + cjColorV5,
01603 (
BYTE *)lpDib +
sizeof(BITMAPINFOHEADER) + cjColorV5,
01604 cjBits);
01605
01606
return lpV5h;
01607 }
01608
01609
01610
01611
01612
01613
01614
01615
01616 LPBITMAPV5HEADER
BMPtoDIBV5(
01617 HBITMAP hbmp,
01618 HPALETTE hpal)
01619 {
01620 LPBITMAPV5HEADER lpV5h;
01621 LPBITMAPINFOHEADER lpbih;
01622
DWORD cbSize;
01623
01624
01625
01626
01627 lpbih =
BMPtoDIB(hbmp, hpal, &cbSize);
01628
01629
if (lpbih) {
01630
01631
01632
01633
01634 lpV5h =
DIBtoDIBV5(lpbih, cbSize);
01635
01636
01637
01638
01639 UserFreePool(lpbih);
01640
01641
return (lpV5h);
01642 }
else {
01643
01644 RIPMSG0(RIP_ERROR,
"Failed on BMPtoDIB(), Why ??");
01645
return NULL;
01646 }
01647 }
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658 HANDLE
xxxGetDummyBitmap(
01659
PWINDOWSTATION pwinsta,
01660
PGETCLIPBDATA pgcd)
01661 {
01662 HANDLE hData =
NULL;
01663
PCLIPDATA pData;
01664 HBITMAP hBitmap;
01665 LPBITMAPINFOHEADER lpbih;
01666 ULONG cjBitmap;
01667 HPALETTE hPal =
NULL;
01668
01669
PCLIP pClipT;
01670
01671
01672
01673
01674
01675
if (
TEST_PUSIF(
PUSIF_PALETTEDISPLAY)) {
01676 hPal =
xxxGetClipboardData(pwinsta, CF_PALETTE, pgcd);
01677 }
01678
01679
01680
01681
01682
01683 pClipT =
FindClipFormat(pwinsta, CF_DIBV5);
01684
if (pClipT && (pClipT->
hData !=
DUMMY_DIB_HANDLE)) {
01685
01686
01687
01688
01689
01690
01691
01692
if (hData =
xxxGetClipboardData(pwinsta, CF_DIBV5, pgcd)) {
01693
01694
01695
01696
01697
01698 pgcd->
uFmtRet = CF_DIBV5;
01699 pgcd->
hPalette = hPal;
01700
01701
return (hData);
01702 }
01703 }
01704
01705
01706
01707
01708
01709 pClipT =
FindClipFormat(pwinsta, CF_DIB);
01710
if (pClipT && (pClipT->
hData !=
DUMMY_DIB_HANDLE)) {
01711 hData =
xxxGetClipboardData(pwinsta, CF_DIB, pgcd);
01712
01713 }
01714
if (hData ==
NULL)
01715
return NULL;
01716
01717
01718
01719
01720
01721
01722
if (pData = (
PCLIPDATA)
HMValidateHandleNoRip(hData,
TYPE_CLIPDATA)) {
01723 lpbih = (LPBITMAPINFOHEADER)&pData->
abData;
01724 cjBitmap = pData->
cbData;
01725 }
else {
01726 UserAssert(pData !=
NULL);
01727
return NULL;
01728 }
01729
01730
01731
01732
01733
01734
01735
01736
01737
if ((cjBitmap >=
sizeof(BITMAPCOREHEADER)) &&
01738 (cjBitmap >= (GreGetBitmapSize((CONST BITMAPINFO *)lpbih,DIB_RGB_COLORS) +
01739 GreGetBitmapBitsSize((CONST BITMAPINFO *)lpbih)))) {
01740
01741
if (hBitmap =
DIBtoBMP(lpbih, hPal)) {
01742
01743
01744
01745
01746 pClipT =
FindClipFormat(pwinsta, CF_BITMAP);
01747
if (pClipT) {
01748
UT_FreeCBFormat(pClipT);
01749 pClipT->
hData = hBitmap;
01750 GreSetBitmapOwner(hBitmap, OBJECT_OWNER_PUBLIC);
01751
01752
01753
01754
01755 pgcd->
uFmtRet = CF_BITMAP;
01756 }
else {
01757
01758
01759
01760 RIPMSG0(RIP_WARNING,
01761
"Clipboard: CF_BITMAP format not available");
01762 GreDeleteObject(hBitmap);
01763 hBitmap =
NULL;
01764 }
01765 }
01766
return (HANDLE)hBitmap;
01767 }
else {
01768 RIPMSG0(RIP_WARNING,
"GetClipboardData, bad DIB format\n");
01769
return NULL;
01770 }
01771
01772 }
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784 HANDLE
xxxGetDummyDib(
01785
PWINDOWSTATION pwinsta,
01786
PGETCLIPBDATA pgcd)
01787 {
01788 HANDLE hData =
NULL;
01789 HBITMAP hBitmap =
NULL;
01790 LPBITMAPINFOHEADER lpDib;
01791 HANDLE hDib;
01792 HPALETTE hPal =
NULL;
01793
01794
PCLIP pClipT;
01795
01796
01797
01798
01799
01800
if (
TEST_PUSIF(
PUSIF_PALETTEDISPLAY)) {
01801 hPal =
xxxGetClipboardData(pwinsta, CF_PALETTE, pgcd);
01802
01803
if (hPal ==
NULL)
01804
return NULL;
01805 }
01806
01807
01808
01809
01810
01811 pClipT =
FindClipFormat(pwinsta, CF_DIBV5);
01812
if (pClipT && (pClipT->
hData !=
DUMMY_DIB_HANDLE)) {
01813
01814
01815
01816
01817
01818
01819
01820
if (hData =
xxxGetClipboardData(pwinsta, CF_DIBV5, pgcd)) {
01821
01822
01823
01824
01825
01826 pgcd->
uFmtRet = CF_DIBV5;
01827 pgcd->
hPalette = hPal;
01828
01829
return (hData);
01830 }
01831 }
01832
01833
01834
01835
01836
01837
01838 pClipT =
FindClipFormat(pwinsta, CF_BITMAP);
01839
if (pClipT && (pClipT->
hData !=
DUMMY_DIB_HANDLE)) {
01840 hBitmap =
xxxGetClipboardData(pwinsta, CF_BITMAP, pgcd);
01841 }
01842
01843
if (hBitmap ==
NULL) {
01844
return NULL;
01845 }
01846
01847
01848
01849
01850 hDib =
NULL;
01851
if (lpDib =
BMPtoDIB(hBitmap, hPal,
NULL)) {
01852
01853
DWORD cbData =
SizeOfDib(lpDib);;
01854
01855
01856
01857
01858
01859
01860
01861 hDib =
_ConvertMemHandle((LPBYTE)lpDib, cbData);
01862 UserFreePool(lpDib);
01863
01864
if (hDib !=
NULL) {
01865
01866
01867
01868
01869 pClipT =
FindClipFormat(pwinsta, CF_DIB);
01870
if (pClipT) {
01871
UT_FreeCBFormat(pClipT);
01872 pClipT->
hData = hDib;
01873
01874
01875
01876
01877 pgcd->
uFmtRet = CF_DIB;
01878 }
else {
01879 PVOID pObj;
01880
01881
01882
01883 RIPMSG0(RIP_WARNING,
01884
"Clipboard: CF_PDIB format not available");
01885 pObj =
HMValidateHandleNoRip(hDib,
TYPE_CLIPDATA);
01886
if (pObj) {
01887
HMFreeObject(pObj);
01888 }
01889 hDib =
NULL;
01890 }
01891 }
01892 }
01893
01894
return hDib;
01895 }
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907 HANDLE
xxxGetDummyDibV5(
01908
PWINDOWSTATION pwinsta,
01909
PGETCLIPBDATA pgcd)
01910 {
01911 HANDLE hData;
01912
PCLIPDATA pData;
01913 LPBITMAPV5HEADER lpDibV5 =
NULL;
01914 HANDLE hDibV5 =
NULL;
01915
01916
PCLIP pClipT;
01917
01918
01919
01920
01921
01922 pClipT =
FindClipFormat(pwinsta, CF_DIB);
01923
if (pClipT && (pClipT->
hData !=
DUMMY_DIB_HANDLE)) {
01924
01925
01926
01927
01928
if (hData =
xxxGetClipboardData(pwinsta, CF_DIB, pgcd)) {
01929
01930
01931
01932
01933
01934
01935
if (pData = (
PCLIPDATA)
HMValidateHandleNoRip(hData,
TYPE_CLIPDATA)) {
01936
01937 LPBITMAPINFOHEADER lpDib = (LPBITMAPINFOHEADER)&pData->
abData;
01938
01939
01940
01941
01942 lpDibV5 =
DIBtoDIBV5(lpDib, pData->
cbData);
01943
01944 }
else {
01945 UserAssert(pData !=
NULL);
01946 }
01947 }
01948 }
01949
01950
if (lpDibV5 ==
NULL) {
01951
01952
01953
01954
01955 pClipT =
FindClipFormat(pwinsta, CF_BITMAP);
01956
if ((pClipT) &&
01957 (pClipT->
hData !=
DUMMY_DIB_HANDLE) &&
01958 (hData =
xxxGetClipboardData(pwinsta, CF_BITMAP, pgcd))) {
01959
01960 HPALETTE hPal =
NULL;
01961
01962
01963
01964
01965
01966
if (
TEST_PUSIF(
PUSIF_PALETTEDISPLAY)) {
01967
01968 hPal =
xxxGetClipboardData(pwinsta, CF_PALETTE, pgcd);
01969
01970
if (hPal ==
NULL)
01971
return NULL;
01972 }
01973
01974
01975
01976
01977 lpDibV5 =
BMPtoDIBV5((HBITMAP)hData, hPal);
01978 }
01979 }
01980
01981
if (lpDibV5 !=
NULL) {
01982
01983
DWORD cbData =
SizeOfDib((LPBITMAPINFOHEADER)lpDibV5);
01984
01985
01986
01987
01988
01989
01990
01991 hDibV5 =
_ConvertMemHandle((LPBYTE)lpDibV5, cbData);
01992 UserFreePool(lpDibV5);
01993
01994
if (hDibV5 !=
NULL) {
01995
01996
01997
01998
01999
02000 pClipT =
FindClipFormat(pwinsta, CF_DIBV5);
02001
if (pClipT) {
02002
UT_FreeCBFormat(pClipT);
02003 pClipT->
hData = hDibV5;
02004
02005
02006
02007
02008 pgcd->
uFmtRet = CF_DIBV5;
02009 }
else {
02010 PVOID pObj;
02011
02012
02013
02014 RIPMSG0(RIP_WARNING,
02015
"Clipboard: CF_DIBV5 format not available");
02016 pObj =
HMValidateHandleNoRip(hDibV5,
TYPE_CLIPDATA);
02017
if (pObj) {
02018
HMFreeObject(pObj);
02019 }
02020 hDibV5 =
NULL;
02021 }
02022 }
02023 }
02024
02025
return hDibV5;
02026 }
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041 HPALETTE
CreateDIBPalette(
02042 LPBITMAPINFOHEADER pbmih,
02043 UINT colors)
02044 {
02045 HPALETTE hpal;
02046
02047
if (colors != 0) {
02048
02049
int i;
02050
BOOL fOldDIB = (pbmih->biSize ==
sizeof(BITMAPCOREHEADER));
02051 RGBTRIPLE *pColorTable;
02052 PLOGPALETTE plp;
02053
02054
02055
02056
02057 plp = (PLOGPALETTE)UserAllocPoolWithQuota(
sizeof(LOGPALETTE) +
02058 (
sizeof(PALETTEENTRY) * 256),
02059 TAG_CLIPBOARDPALETTE);
02060
02061
if (plp ==
NULL) {
02062
return NULL;
02063 }
02064
02065 pColorTable = (RGBTRIPLE *)((LPSTR)pbmih + (WORD)pbmih->biSize);
02066 plp->palVersion = 0x300;
02067
02068
if (fOldDIB || (pbmih->biClrUsed == 0)) {
02069 UserAssert(colors <= 0xFFFF);
02070 plp->palNumEntries = (WORD)colors;
02071 }
else {
02072 UserAssert(pbmih->biClrUsed <= 0xFFFF);
02073 plp->palNumEntries = (WORD)pbmih->biClrUsed;
02074 }
02075
02076
for (i = 0; i < (
int)(plp->palNumEntries); i++) {
02077
02078 plp->palPalEntry[i].peRed = pColorTable->rgbtRed;
02079 plp->palPalEntry[i].peGreen = pColorTable->rgbtGreen;
02080 plp->palPalEntry[i].peBlue = pColorTable->rgbtBlue;
02081 plp->palPalEntry[i].peFlags = (
BYTE)PC_NOCOLLAPSE;
02082
02083
if (fOldDIB) {
02084 pColorTable++;
02085 }
else {
02086 pColorTable = (RGBTRIPLE *)((LPSTR)pColorTable+
sizeof(RGBQUAD));
02087 }
02088 }
02089
02090 hpal = GreCreatePalette((LPLOGPALETTE)plp);
02091 UserFreePool(plp);
02092
02093 }
else {
02094 hpal = GreCreateHalftonePalette(
HDCBITS());
02095 }
02096
02097 GreSetPaletteOwner(hpal, OBJECT_OWNER_PUBLIC);
02098
02099
return hpal;
02100 }
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 HANDLE
xxxGetDummyPalette(
02112
PWINDOWSTATION pwinsta,
02113
PGETCLIPBDATA pgcd)
02114 {
02115 HANDLE hData;
02116
PCLIPDATA pData;
02117 LPBITMAPINFOHEADER lpbih;
02118 HPALETTE hPal;
02119
02120
PCLIP pClipT;
02121
02122
02123
02124
02125
02126
UINT uFmt = CF_DIBV5;
02127
02128
if ((pClipT =
FindClipFormat(pwinsta, uFmt)) !=
NULL)
02129 {
02130
if (pClipT->
hData !=
DUMMY_DIB_HANDLE) {
02131
02132
02133
02134
02135 }
else {
02136
02137
02138
02139
02140 uFmt = CF_DIB;
02141 }
02142 }
02143
02144
02145
02146
02147
02148
02149 hData = (HANDLE)
xxxGetClipboardData(pwinsta, uFmt, pgcd);
02150 UserAssert(hData >
DUMMY_MAX_HANDLE);
02151
02152
if (hData ==
NULL)
02153
return NULL;
02154
02155
02156
02157
02158
02159
02160
if (pData = (
PCLIPDATA)
HMValidateHandle(hData,
TYPE_CLIPDATA)) {
02161 lpbih = (LPBITMAPINFOHEADER)&pData->
abData;
02162 }
else {
02163 UserAssert(pData !=
NULL);
02164
return NULL;
02165 }
02166
02167
if ((pClipT =
FindClipFormat(pwinsta, CF_PALETTE)) ==
NULL) {
02168 RIPMSG0(RIP_WARNING,
02169
"Clipboard: CF_PALETTE format not available");
02170
return NULL;
02171 }
02172
02173
02174
02175
02176
02177
02178
02179
02180 hPal =
CreateDIBPalette(lpbih, lpbih->biClrUsed);
02181
02182
if (hPal !=
NULL) {
02183
UT_FreeCBFormat(pClipT);
02184 pClipT->
hData = hPal;
02185 GreSetPaletteOwner(hPal, OBJECT_OWNER_PUBLIC);
02186 }
02187
02188
return (HANDLE)hPal;
02189 }
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200 HANDLE
xxxGetDummyText(
02201
PWINDOWSTATION pwinsta,
02202 UINT fmt,
02203
PGETCLIPBDATA pgcd)
02204 {
02205 HANDLE hText;
02206
PCLIP pClipT;
02207
UINT uFmtMain;
02208
UINT uFmtAlt;
02209
BOOL bMain =
TRUE;
02210
02211
02212
02213
02214
switch (fmt) {
02215
case CF_TEXT:
02216 uFmtMain = CF_UNICODETEXT;
02217 uFmtAlt = CF_OEMTEXT;
02218
goto GetRealText;
02219
02220
case CF_OEMTEXT:
02221 uFmtMain = CF_UNICODETEXT;
02222 uFmtAlt = CF_TEXT;
02223
goto GetRealText;
02224
02225
case CF_UNICODETEXT:
02226 uFmtMain = CF_TEXT;
02227 uFmtAlt = CF_OEMTEXT;
02228
02229 GetRealText:
02230
02231
if ((pClipT =
FindClipFormat(pwinsta, uFmtMain)) ==
NULL)
02232
return NULL;
02233
02234
if (pClipT->
hData !=
DUMMY_TEXT_HANDLE) {
02235
02236
if (
xxxGetClipboardData(pwinsta, uFmtMain, pgcd))
02237
break;
02238
02239
return NULL;
02240 }
02241
02242
if ((pClipT =
FindClipFormat(pwinsta, uFmtAlt)) ==
NULL)
02243
return NULL;
02244
02245
if (pClipT->
hData !=
DUMMY_TEXT_HANDLE) {
02246 bMain =
FALSE;
02247
02248
if (
xxxGetClipboardData(pwinsta, uFmtAlt, pgcd))
02249
break;
02250 }
02251
02252
02253
02254
02255
02256
default:
02257
return NULL;
02258 }
02259
02260
02261
02262
02263
02264
02265 pClipT =
FindClipFormat(pwinsta, bMain? uFmtMain:uFmtAlt);
02266
02267
if (pClipT ==
NULL) {
02268 RIPMSG1(RIP_WARNING,
02269
"Clipboard: GetDummyText, format 0x%lX not available", bMain? uFmtMain:uFmtAlt);
02270
return NULL;
02271 }
02272
02273
02274
02275
02276 pgcd->
uFmtRet = pClipT->
fmt;
02277 hText = pClipT->
hData;
02278
02279
02280
02281
02282
02283
if(pClipT =
FindClipFormat(pwinsta, CF_LOCALE)) {
02284 pgcd->
hLocale = pClipT->
hData;
02285 }
else {
02286 pgcd->
hLocale =
NULL;
02287 }
02288
02289
return hText;
02290 }
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 HANDLE
xxxGetRenderData(
02304
PWINDOWSTATION pwinsta,
02305 UINT fmt)
02306 {
02307
BOOL fClipboardChangedOld;
02308
TL tlpwndClipOwner;
02309
PCLIP pClip;
02310
02311
02312
02313
02314
02315
02316
if (pwinsta->
spwndClipOwner !=
NULL) {
02317
02318
02319
02320
02321
02322
02323
02324
02325 fClipboardChangedOld = pwinsta->
fClipboardChanged;
02326 pwinsta->
fInDelayedRendering =
TRUE;
02327
ThreadLockAlways(pwinsta->
spwndClipOwner, &tlpwndClipOwner);
02328
xxxSendMessage(pwinsta->
spwndClipOwner, WM_RENDERFORMAT, fmt, 0
L);
02329
ThreadUnlock(&tlpwndClipOwner);
02330 pwinsta->
fClipboardChanged = fClipboardChangedOld;
02331 pwinsta->
fInDelayedRendering =
FALSE;
02332
02333 }
02334
02335
if ((pClip =
FindClipFormat(pwinsta, fmt)) ==
NULL) {
02336 RIPMSG1(RIP_WARNING,
02337
"Clipboard: Meta Render/Clone format 0x%lX not available", fmt);
02338
return NULL;
02339 }
02340
02341
02342
02343
return pClip->
hData;
02344 }
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356 HANDLE
xxxGetClipboardData(
02357
PWINDOWSTATION pwinsta,
02358 UINT fmt,
02359
PGETCLIPBDATA pgcd)
02360 {
02361
PCLIP pClip;
02362 HANDLE hData;
02363
02364
02365
02366
02367
if (pwinsta->
ptiClipLock !=
PtiCurrent()) {
02368 RIPERR0(ERROR_CLIPBOARD_NOT_OPEN, RIP_VERBOSE,
"GetClipboardData: clipboard not open");
02369
return NULL;
02370 }
02371
02372
02373
02374
02375
if ((pClip =
FindClipFormat(pwinsta, fmt)) ==
NULL) {
02376 RIPMSG1(RIP_VERBOSE,
"Clipboard: Requested format 0x%lX not available", fmt);
02377
return NULL;
02378 }
02379
02380
02381
02382
02383
02384
02385
02386
if (
IsMetaDummyHandle(pClip->
hData)) {
02387
02388
if (fmt == CF_ENHMETAFILE) {
02389 fmt = CF_METAFILEPICT;
02390 }
else if (fmt == CF_METAFILEPICT) {
02391 fmt = CF_ENHMETAFILE;
02392 }
else {
02393 RIPMSG0(RIP_WARNING,
02394
"Clipboard: Meta Render/Clone expects a metafile type");
02395 }
02396
02397
if ((pClip =
FindClipFormat(pwinsta, fmt)) ==
NULL) {
02398 RIPMSG1(RIP_WARNING,
02399
"Clipboard: Meta Render/Clone format 0x%lX not available", fmt);
02400
return NULL;
02401 }
02402 }
02403
02404
02405
02406
02407
02408 hData = pClip->
hData;
02409
02410
02411
02412
02413
02414
02415
02416
02417
if ((hData ==
NULL) || (hData ==
DUMMY_METARENDER_HANDLE)) {
02418
02419 hData =
xxxGetRenderData(pwinsta, fmt);
02420
02421 }
else if (hData ==
DUMMY_DIB_HANDLE) {
02422
02423
switch (fmt) {
02424
case CF_DIB:
02425 hData =
xxxGetDummyDib(pwinsta, pgcd);
02426
break;
02427
case CF_DIBV5:
02428 hData =
xxxGetDummyDibV5(pwinsta, pgcd);
02429
break;
02430
case CF_BITMAP:
02431 hData =
xxxGetDummyBitmap(pwinsta, pgcd);
02432
break;
02433
case CF_PALETTE:
02434 hData =
xxxGetDummyPalette(pwinsta, pgcd);
02435
break;
02436 }
02437
02438 }
else if (hData ==
DUMMY_TEXT_HANDLE) {
02439
02440 hData =
xxxGetDummyText(pwinsta, fmt, pgcd);
02441 }
else {
02442
02443
02444
02445
if (pgcd)
02446 pgcd->
fGlobalHandle = pClip->
fGlobalHandle;
02447
02448
return hData;
02449 }
02450
02451
02452
02453
02454
02455
02456
if ((pClip =
FindClipFormat(pwinsta, fmt)) ==
NULL) {
02457 RIPMSG1(RIP_VERBOSE,
"Clipboard: Requested format 0x%lX not available", fmt);
02458
return NULL;
02459 }
02460
02461
02462
02463
02464
if (pgcd)
02465 pgcd->
fGlobalHandle = pClip->
fGlobalHandle;
02466
02467
return hData;
02468 }
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482 PCLIP FindClipFormat(
02483
PWINDOWSTATION pwinsta,
02484 UINT format)
02485 {
02486
PCLIP pClip;
02487
int iFmt;
02488
02489
if ((
format != 0) && ((pClip = pwinsta->
pClipBase) !=
NULL)) {
02490
02491
for (iFmt = pwinsta->
cNumClipFormats; iFmt-- != 0;) {
02492
02493
if (pClip->
fmt ==
format)
02494
return pClip;
02495
02496 pClip++;
02497 }
02498 }
02499
02500
return NULL;
02501 }
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514 int _GetPriorityClipboardFormat(
02515 PUINT lpPriorityList,
02516
int cfmts)
02517 {
02518
PWINDOWSTATION pwinsta;
02519
PCLIP pClip;
02520
int iFmt;
02521
UINT fmt;
02522
02523
02524
02525
02526
if ((pwinsta =
CheckClipboardAccess()) ==
NULL)
02527
return 0;
02528
02529
02530
02531
02532
if ((pwinsta->
cNumClipFormats == 0) || (pwinsta->
pClipBase ==
NULL))
02533
return 0;
02534
02535
02536
02537
02538
while (cfmts-- > 0) {
02539
02540 fmt = *lpPriorityList;
02541
02542
if (fmt != 0) {
02543
02544 pClip = pwinsta->
pClipBase;
02545
02546
for (iFmt = pwinsta->
cNumClipFormats; iFmt-- != 0; pClip++) {
02547
02548
if (pClip->
fmt == fmt)
02549
return fmt;
02550 }
02551 }
02552
02553 lpPriorityList++;
02554 }
02555
02556
02557
02558
02559
return -1;
02560 }
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572 PWND xxxSetClipboardViewer(
02573
PWND pwndClipViewerNew)
02574 {
02575
TL tlpwinsta;
02576
PWINDOWSTATION pwinsta;
02577 HWND hwndClipViewerOld;
02578
PTHREADINFO ptiCurrent;
02579
02580
CheckLock(pwndClipViewerNew);
02581
02582
02583
02584
02585
02586
02587
02588
if ((pwinsta =
CheckClipboardAccess()) ==
NULL)
02589
return NULL;
02590
02591 ptiCurrent =
PtiCurrent();
02592
02593
ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);
02594
02595 hwndClipViewerOld =
HW(pwinsta->
spwndClipViewer);
02596
Lock(&pwinsta->
spwndClipViewer, pwndClipViewerNew);
02597
02598
xxxDrawClipboard(pwinsta);
02599
02600
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
02601
02602
if (hwndClipViewerOld !=
NULL)
02603
return RevalidateHwnd(hwndClipViewerOld);
02604
02605
return NULL;
02606 }
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618 BOOL xxxChangeClipboardChain(
02619
PWND pwndRemove,
02620
PWND pwndNewNext)
02621 {
02622
TL tlpwinsta;
02623
PWINDOWSTATION pwinsta;
02624
BOOL result;
02625
TL tlpwndClipViewer;
02626
PTHREADINFO ptiCurrent;
02627
02628
CheckLock(pwndRemove);
02629
CheckLock(pwndNewNext);
02630
02631
02632
02633
02634
if ((pwinsta =
CheckClipboardAccess()) ==
NULL)
02635
return FALSE;
02636
02637
02638
02639
02640
02641 ptiCurrent =
PtiCurrent();
02642
02643
if (
GETPTI(pwndRemove) != ptiCurrent) {
02644 RIPMSG0(RIP_WARNING,
"Clipboard: ChangeClipboardChain will not remove cross threads");
02645
return FALSE;
02646 }
02647
02648
if (pwinsta->
spwndClipViewer ==
NULL) {
02649 RIPMSG0(RIP_WARNING,
"Clipboard: ChangeClipboardChain has no viewer window");
02650
return FALSE;
02651 }
02652
02653
ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);
02654
02655
if (pwndRemove == pwinsta->
spwndClipViewer) {
02656
02657
Lock(&pwinsta->
spwndClipViewer, pwndNewNext);
02658 result =
TRUE;
02659
02660 }
else {
02661
02662
ThreadLockAlways(pwinsta->
spwndClipViewer, &tlpwndClipViewer);
02663 result = (
BOOL)
xxxSendMessage(pwinsta->
spwndClipViewer,
02664 WM_CHANGECBCHAIN,
02665 (WPARAM)
HW(pwndRemove),
02666 (LPARAM)
HW(pwndNewNext));
02667
ThreadUnlock(&tlpwndClipViewer);
02668 }
02669
02670
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
02671
02672
return result;
02673 }
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687 VOID DisownClipboard(
PWND pwndClipOwner)
02688 {
02689
TL tlpwinsta;
02690
PWINDOWSTATION pwinsta;
02691
int iFmt;
02692
int cFmts;
02693
PCLIP pClip;
02694
PCLIP pClipOut;
02695
BOOL fKeepDummyHandle;
02696
PTHREADINFO ptiCurrent;
02697
02698
if ((pwinsta =
CheckClipboardAccess()) ==
NULL)
02699
return;
02700
02701 ptiCurrent =
PtiCurrent();
02702
02703
ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);
02704
02705
xxxSendClipboardMessage(pwinsta, WM_RENDERALLFORMATS);
02706
02707 pClipOut = pClip = pwinsta->
pClipBase;
02708 fKeepDummyHandle =
FALSE;
02709
02710
for (cFmts = 0, iFmt = pwinsta->
cNumClipFormats; iFmt-- != 0;) {
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
if (pClip->hData !=
NULL) {
02722
02723
if ((pClip->hData !=
DUMMY_TEXT_HANDLE) ||
02724 ((pClip->hData ==
DUMMY_TEXT_HANDLE) && fKeepDummyHandle)) {
02725
02726 cFmts++;
02727 *pClipOut++ = *pClip;
02728
02729
if (
IsTextHandle(pClip->fmt, pClip->hData)) {
02730 fKeepDummyHandle =
TRUE;
02731 }
02732 }
02733 }
02734
02735 pClip++;
02736 }
02737
02738
02739
02740
02741
02742
if (pwndClipOwner == pwinsta->
spwndClipOwner) {
02743
Unlock(&pwinsta->
spwndClipOwner);
02744 }
else {
02745 RIPMSG2(RIP_WARNING,
"DisownClipboard: pwndClipOwner changed from %#p to %#p",
02746 pwndClipOwner, pwinsta->
spwndClipOwner);
02747 }
02748
02749
02750
02751
02752
if (cFmts != pwinsta->
cNumClipFormats) {
02753 pwinsta->
fClipboardChanged =
TRUE;
02754 pwinsta->
iClipSequenceNumber++;
02755 }
02756
02757 pwinsta->
cNumClipFormats = cFmts;
02758
02759
02760
02761
02762
02763
if (pwinsta->
fClipboardChanged) {
02764
xxxDrawClipboard(pwinsta);
02765
MungeClipData(pwinsta);
02766 }
02767
02768
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
02769 }
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779 VOID ForceEmptyClipboard(
02780
PWINDOWSTATION pwinsta)
02781 {
02782
02783 pwinsta->
ptiClipLock = ((
PTHREADINFO)(W32GetCurrentThread()));
02784
02785
02786
02787
Unlock(&pwinsta->
spwndClipOwner);
02788
Unlock(&pwinsta->
spwndClipViewer);
02789
Unlock(&pwinsta->
spwndClipOpen);
02790
02791
xxxEmptyClipboard(pwinsta);
02792
02793
02794
02795
02796
02797
if (!(pwinsta->
dwWSF_Flags &
WSF_DYING))
02798
xxxCloseClipboard(pwinsta);
02799 }