00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "mscms.h"
00020
#include "objbase.h"
00021
#include "initguid.h"
00022
#include "devguid.h"
00023
#include "sti.h"
00024
00025 #define TAG_DEVICESETTINGS 'devs'
00026 #define TAG_MS01 'MS01'
00027 #define TAG_MS02 'MS02'
00028 #define TAG_MS03 'MS03'
00029
00030 #define ID_MSFT_REVERSED 'tfsm'
00031 #define ID_MEDIATYPE_REVERSED 'aidm'
00032 #define ID_DITHER_REVERSED 'ntfh'
00033 #define ID_RESLN_REVERSED 'nlsr'
00034
00035 #define DEVICE_PROFILE_DATA 1
00036 #define DEVICE_PROFILE_ENUMMODE 2
00037
00038
00039
00040
00041
00042 typedef enum {
00043
NOMATCH = 0,
00044
MATCH = 1,
00045
EXACT_MATCH = 2,
00046 }
MATCHTYPE;
00047
00048
typedef struct tagREGDATA {
00049 DWORD dwRefCount;
00050 DWORD dwManuID;
00051 DWORD dwModelID;
00052 }
REGDATA, *
PREGDATA;
00053
00054 typedef struct tagSCANNERDATA {
00055 PWSTR
pDeviceName;
00056 HINSTANCE
hModule;
00057 PSTI pSti;
00058 }
SCANNERDATA, *
PSCANNERDATA;
00059
00060 typedef BOOL (WINAPI *
PFNOPENDEVICE)(PTSTR, LPHANDLE, PTSTR);
00061 typedef BOOL (WINAPI *
PFNCLOSEDEVICE)(HANDLE);
00062 typedef DWORD (WINAPI *
PFNGETDEVICEDATA)(HANDLE, PTSTR, PTSTR, PDWORD,
PBYTE,
DWORD, PDWORD);
00063 typedef DWORD (WINAPI *
PFNSETDEVICEDATA)(HANDLE, PTSTR, PTSTR,
DWORD,
PBYTE,
DWORD);
00064 typedef HRESULT (__stdcall *PFNSTICREATEINSTANCE)(HINSTANCE,
DWORD,
PSTI*, LPDWORD);
00065
00066
00067
00068
00069
00070
BOOL InternalGetColorDirectory(LPCTSTR, PTSTR, DWORD*);
00071
BOOL InternalInstallColorProfile(LPCTSTR, LPCTSTR);
00072
BOOL InternalUninstallColorProfile(LPCTSTR, LPCTSTR, BOOL);
00073
BOOL InternalAssociateColorProfileWithDevice(LPCTSTR, LPCTSTR, LPCTSTR);
00074
BOOL InternalDisassociateColorProfileFromDevice(LPCTSTR, LPCTSTR, LPCTSTR);
00075
BOOL InternalEnumColorProfiles(LPCTSTR, PENUMTYPE, PBYTE, PDWORD, PDWORD);
00076
BOOL InternalSetSCSProfile(LPCTSTR, DWORD, LPCTSTR);
00077
BOOL InternalGetSCSProfile(LPCTSTR, DWORD, PTSTR, PDWORD);
00078
VOID ConvertDwordToString(DWORD, PTSTR);
00079 PTSTR
ConvertClassIdToClassString(DWORD);
00080
BOOL GetProfileClassString(LPCTSTR, PTSTR, PPROFILEHEADER);
00081
BOOL GetDeviceData(LPCTSTR, DWORD, DWORD, PVOID*, PDWORD, BOOL);
00082
BOOL SetDeviceData(LPCTSTR, DWORD, DWORD, PVOID, DWORD);
00083
BOOL IGetDeviceData(LPCTSTR, DWORD, DWORD, PVOID*, PDWORD, BOOL);
00084
BOOL ISetDeviceData(LPCTSTR, DWORD, DWORD, PVOID, DWORD);
00085
BOOL IsStringInMultiSz(PTSTR, PTSTR);
00086
DWORD RemoveStringFromMultiSz(PTSTR, PTSTR, DWORD);
00087
VOID InsertInBuffer(PBYTE, PBYTE, PTSTR);
00088
MATCHTYPE DoesProfileMatchEnumRecord(PTSTR, PENUMTYPE);
00089
MATCHTYPE CheckResMedHftnMatch(HPROFILE, PENUMTYPE);
00090
BOOL DwordMatches(PSETTINGS, DWORD);
00091
BOOL QwordMatches(PSETTINGS, PDWORD);
00092
BOOL WINAPI
OpenPrtr(PTSTR, LPHANDLE, PTSTR);
00093
BOOL WINAPI
ClosePrtr(HANDLE);
00094
DWORD WINAPI
GetPrtrData(HANDLE, PTSTR, PTSTR, PDWORD, PBYTE, DWORD, PDWORD);
00095
DWORD WINAPI
SetPrtrData(HANDLE, PTSTR, PTSTR, DWORD, PBYTE, DWORD);
00096
BOOL WINAPI
OpenMonitor(PTSTR, LPHANDLE, PTSTR);
00097
BOOL WINAPI
CloseMonitor(HANDLE);
00098
DWORD WINAPI
GetMonitorData(HANDLE, PTSTR, PTSTR, PDWORD, PBYTE, DWORD, PDWORD);
00099
DWORD WINAPI
SetMonitorData(HANDLE, PTSTR, PTSTR, DWORD, PBYTE, DWORD);
00100
BOOL WINAPI
OpenScanner(PTSTR, LPHANDLE, PTSTR);
00101
BOOL WINAPI
CloseScanner(HANDLE);
00102
DWORD WINAPI
GetScannerData(HANDLE, PTSTR, PTSTR, PDWORD, PBYTE, DWORD, PDWORD);
00103
DWORD WINAPI
SetScannerData(HANDLE, PTSTR, PTSTR, DWORD, PBYTE, DWORD);
00104
#ifdef _WIN95_
00105
BOOL LoadSetupAPIDll(VOID);
00106
#else
00107
VOID ChangeICMSetting(LPCTSTR, LPCTSTR, DWORD);
00108
#endif // _WIN95_
00109
00110
00111
00112
00113
typedef WINSETUPAPI HKEY
00114 (WINAPI *
FP_SetupDiOpenDevRegKey)(
00115 IN HDEVINFO DeviceInfoSet,
00116 IN PSP_DEVINFO_DATA DeviceInfoData,
00117 IN
DWORD Scope,
00118 IN
DWORD HwProfile,
00119 IN
DWORD KeyType,
00120 IN REGSAM samDesired
00121 );
00122
00123
typedef WINSETUPAPI
BOOL
00124 (WINAPI *
FP_SetupDiDestroyDeviceInfoList)(
00125 IN HDEVINFO DeviceInfoSet
00126 );
00127
00128
typedef WINSETUPAPI
BOOL
00129 (WINAPI *
FP_SetupDiEnumDeviceInfo)(
00130 IN HDEVINFO DeviceInfoSet,
00131 IN
DWORD MemberIndex,
00132 OUT PSP_DEVINFO_DATA DeviceInfoData
00133 );
00134
00135
#if !defined(_WIN95_)
00136
typedef WINSETUPAPI
BOOL
00137 (WINAPI *
FP_SetupDiGetDeviceInstanceId)(
00138 IN HDEVINFO DeviceInfoSet,
00139 IN PSP_DEVINFO_DATA DeviceInfoData,
00140 OUT PWSTR DeviceInstanceId,
00141 IN
DWORD DeviceInstanceIdSize,
00142 OUT PDWORD RequiredSize OPTIONAL
00143 );
00144
00145
typedef WINSETUPAPI HDEVINFO
00146 (WINAPI *
FP_SetupDiGetClassDevs)(
00147 IN LPGUID ClassGuid, OPTIONAL
00148 IN PCWSTR Enumerator, OPTIONAL
00149 IN HWND hwndParent, OPTIONAL
00150 IN
DWORD Flags
00151 );
00152
#else
00153
typedef WINSETUPAPI
BOOL
00154 (WINAPI *
FP_SetupDiGetDeviceInstanceId)(
00155 IN HDEVINFO DeviceInfoSet,
00156 IN PSP_DEVINFO_DATA DeviceInfoData,
00157 OUT PSTR DeviceInstanceId,
00158 IN
DWORD DeviceInstanceIdSize,
00159 OUT PDWORD RequiredSize OPTIONAL
00160 );
00161
00162
typedef WINSETUPAPI HDEVINFO
00163 (WINAPI *
FP_SetupDiGetClassDevs)(
00164 IN LPGUID ClassGuid, OPTIONAL
00165 IN PCSTR Enumerator, OPTIONAL
00166 IN HWND hwndParent, OPTIONAL
00167 IN
DWORD Flags
00168 );
00169
#endif
00170
00171 HMODULE
ghModSetupAPIDll =
NULL;
00172
00173 FP_SetupDiOpenDevRegKey fpSetupDiOpenDevRegKey =
NULL;
00174 FP_SetupDiDestroyDeviceInfoList fpSetupDiDestroyDeviceInfoList =
NULL;
00175 FP_SetupDiEnumDeviceInfo fpSetupDiEnumDeviceInfo =
NULL;
00176 FP_SetupDiGetDeviceInstanceId fpSetupDiGetDeviceInstanceId =
NULL;
00177 FP_SetupDiGetClassDevs fpSetupDiGetClassDevs =
NULL;
00178
00179
00180
00181
00182
00183 TCHAR *
gszDispProfiles[] = {
00184 __TEXT(
"mnB22G15.icm"),
00185 __TEXT(
"mnB22G18.icm"),
00186 __TEXT(
"mnB22G21.icm"),
00187 __TEXT(
"mnEBUG15.icm"),
00188 __TEXT(
"mnEBUG18.icm"),
00189 __TEXT(
"mnEBUG21.icm"),
00190 __TEXT(
"mnP22G15.icm"),
00191 __TEXT(
"mnP22G18.icm"),
00192 __TEXT(
"mnP22G21.icm"),
00193 __TEXT(
"Diamond Compatible 9300K G2.2.icm"),
00194 __TEXT(
"Hitachi Compatible 9300K G2.2.icm"),
00195 __TEXT(
"NEC Compatible 9300K G2.2.icm"),
00196 __TEXT(
"Trinitron Compatible 9300K G2.2.icm"),
00197 };
00198
00199 TCHAR *
gpszClasses[] = {
00200 __TEXT(
"mntr"),
00201 __TEXT(
"prtr"),
00202 __TEXT(
"scnr"),
00203 __TEXT(
"link"),
00204 __TEXT(
"abst"),
00205 __TEXT(
"spac"),
00206 __TEXT(
"nmcl")
00207 };
00208
00209 #define INDEX_CLASS_MONITOR 0
00210 #define INDEX_CLASS_PRINTER 1
00211 #define INDEX_CLASS_SCANNER 2
00212 #define INDEX_CLASS_LINK 3
00213 #define INDEX_CLASS_ABSTRACT 4
00214 #define INDEX_CLASS_COLORSPACE 5
00215 #define INDEX_CLASS_NAMED 6
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
#ifdef UNICODE // Windows NT versions
00239
00240
BOOL WINAPI
00241
GetColorDirectoryA(
00242 PCSTR pMachineName,
00243 PSTR pBuffer,
00244 PDWORD pdwSize
00245 )
00246 {
00247 PWSTR pwszMachineName =
NULL;
00248 PWSTR pwBuffer =
NULL;
00249
DWORD dwSize;
00250
DWORD dwErr = 0;
00251
BOOL rc =
TRUE;
00252
00253
TRACEAPI((__TEXT(
"GetColorDirectoryA\n")));
00254
00255
00256
00257
00258
00259
if (!pdwSize ||
00260 IsBadWritePtr(pdwSize,
sizeof(
DWORD)) ||
00261 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)))
00262 {
00263
WARNING((__TEXT(
"Invalid parameter to GetColorDirectory\n")));
00264 SetLastError(ERROR_INVALID_PARAMETER);
00265
return FALSE;
00266 }
00267
00268
00269
00270
00271
00272
if (pMachineName)
00273 {
00274 rc =
ConvertToUnicode(pMachineName, &pwszMachineName,
TRUE);
00275 }
00276
else
00277 pwszMachineName =
NULL;
00278
00279 dwSize = *pdwSize *
sizeof(WCHAR);
00280
00281
00282
00283
00284
00285
if (pBuffer && dwSize)
00286 {
00287 pwBuffer = (PWSTR)
MemAlloc(dwSize);
00288
if (! pwBuffer)
00289 {
00290
WARNING((__TEXT(
"Error allocating memory for Unicode string\n")));
00291 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00292 rc =
FALSE;
00293
goto EndGetColorDirectoryA;
00294 }
00295 }
00296
00297 rc = rc &&
InternalGetColorDirectory(pwszMachineName, pwBuffer, &dwSize);
00298
00299 *pdwSize = dwSize /
sizeof(WCHAR);
00300
00301
00302
00303
00304
00305
if (pwBuffer)
00306 {
00307 rc = rc &&
ConvertToAnsi(pwBuffer, &pBuffer,
FALSE);
00308 }
00309
00310 EndGetColorDirectoryA:
00311
if (pwszMachineName)
00312 {
00313
MemFree(pwszMachineName);
00314 }
00315
00316
if (pwBuffer)
00317 {
00318
MemFree(pwBuffer);
00319 }
00320
00321
return rc;
00322 }
00323
00324
BOOL WINAPI
00325
GetColorDirectoryW(
00326 PCWSTR pMachineName,
00327 PWSTR pBuffer,
00328 PDWORD pdwSize
00329 )
00330 {
00331
TRACEAPI((__TEXT(
"GetColorDirectoryW\n")));
00332
00333
00334
00335
00336
00337
return InternalGetColorDirectory(pMachineName, pBuffer, pdwSize);
00338 }
00339
00340
#else // Windows 95 versions
00341
00342
BOOL WINAPI
00343 GetColorDirectoryA(
00344 PCSTR pMachineName,
00345 PSTR pBuffer,
00346 PDWORD pdwSize
00347 )
00348 {
00349
TRACEAPI((__TEXT(
"GetColorDirectoryA\n")));
00350
00351
00352
00353
00354
00355
return InternalGetColorDirectory(pMachineName, pBuffer, pdwSize);
00356 }
00357
00358
BOOL WINAPI
00359 GetColorDirectoryW(
00360 PCWSTR pMachineName,
00361 PWSTR pBuffer,
00362 PDWORD pdwSize
00363 )
00364 {
00365 PSTR pszMachineName =
NULL;
00366 PSTR pszBuffer =
NULL;
00367
DWORD dwSize;
00368
BOOL rc =
TRUE;
00369
00370
TRACEAPI((__TEXT(
"GetColorDirectoryW\n")));
00371
00372
00373
00374
00375
00376
if (!pdwSize ||
00377 IsBadWritePtr(pdwSize,
sizeof(
DWORD)) ||
00378 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)))
00379 {
00380
WARNING((__TEXT(
"Invalid parameter to GetColorDirectory\n")));
00381 SetLastError(ERROR_INVALID_PARAMETER);
00382
return FALSE;
00383 }
00384
00385
00386
00387
00388
00389
if (pMachineName)
00390 {
00391 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
00392 }
00393
else
00394 pszMachineName =
NULL;
00395
00396
00397
00398
00399
00400 dwSize = *pdwSize /
sizeof(WCHAR);
00401
00402
if (pBuffer && dwSize)
00403 {
00404 pszBuffer = (PSTR)
MemAlloc(dwSize);
00405
if (! pszBuffer)
00406 {
00407
WARNING((__TEXT(
"Error allocating memory for Ansi string\n")));
00408 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00409 rc =
FALSE;
00410
goto EndGetColorDirectoryW;
00411 }
00412 }
00413
00414 rc = rc &&
InternalGetColorDirectory(pszMachineName, pszBuffer, &dwSize);
00415
00416 *pdwSize = dwSize *
sizeof(WCHAR);
00417
00418
00419
00420
00421
00422
if (pszBuffer)
00423 {
00424 rc = rc &&
ConvertToUnicode(pszBuffer, &pBuffer,
FALSE);
00425 }
00426
00427 EndGetColorDirectoryW:
00428
if (pszMachineName)
00429 {
00430
MemFree(pszMachineName);
00431 }
00432
00433
if (pszBuffer)
00434 {
00435
MemFree(pszBuffer);
00436 }
00437
00438
return rc;
00439 }
00440
00441
#endif // ! UNICODE
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
#ifdef UNICODE // Windows NT versions
00464
00465
BOOL WINAPI
00466
InstallColorProfileA(
00467 PCSTR pMachineName,
00468 PCSTR pProfileName
00469 )
00470
00471 {
00472 PWSTR pwszMachineName =
NULL;
00473 PWSTR pwszProfileName =
NULL;
00474
BOOL rc =
TRUE;
00475
00476
TRACEAPI((__TEXT(
"InstallColorProfileA\n")));
00477
00478
00479
00480
00481
00482
if (!pProfileName)
00483 {
00484
WARNING((__TEXT(
"Invalid parameter to InstallColorProfile\n")));
00485 SetLastError(ERROR_INVALID_PARAMETER);
00486
return FALSE;
00487 }
00488
00489
00490
00491
00492
00493
if (pMachineName)
00494 {
00495 rc =
ConvertToUnicode(pMachineName, &pwszMachineName, TRUE);
00496 }
00497
else
00498 pwszMachineName =
NULL;
00499
00500
00501
00502
00503
00504 rc = rc &&
ConvertToUnicode(pProfileName, &pwszProfileName, TRUE);
00505
00506
00507
00508
00509
00510 rc = rc &&
InternalInstallColorProfile(pwszMachineName, pwszProfileName);
00511
00512
00513
00514
00515
00516
if (pwszProfileName)
00517 {
00518
MemFree(pwszProfileName);
00519 }
00520
00521
if (pwszMachineName)
00522 {
00523
MemFree(pwszMachineName);
00524 }
00525
00526
return rc;
00527 }
00528
00529
00530
BOOL WINAPI
00531
InstallColorProfileW(
00532 PCWSTR pMachineName,
00533 PCWSTR pProfileName
00534 )
00535 {
00536
TRACEAPI((__TEXT(
"InstallColorProfileW\n")));
00537
00538
00539
00540
00541
00542
return InternalInstallColorProfile(pMachineName, pProfileName);
00543 }
00544
00545
00546
#else // Windows 95 versions
00547
00548
BOOL WINAPI
00549 InstallColorProfileA(
00550 PCSTR pMachineName,
00551 PCSTR pProfileName
00552 )
00553 {
00554
TRACEAPI((__TEXT(
"InstallColorProfileA\n")));
00555
00556
00557
00558
00559
00560
return InternalInstallColorProfile(pMachineName, pProfileName);
00561 }
00562
00563
00564
BOOL WINAPI
00565 InstallColorProfileW(
00566 PCWSTR pMachineName,
00567 PCWSTR pProfileName
00568 )
00569 {
00570 PSTR pszMachineName =
NULL;
00571 PSTR pszProfileName =
NULL;
00572
BOOL rc =
TRUE;
00573
00574
TRACEAPI((__TEXT(
"InstallColorProfileW\n")));
00575
00576
00577
00578
00579
00580
if (!pProfileName)
00581 {
00582
WARNING((__TEXT(
"Invalid parameter to InstallColorProfile\n")));
00583 SetLastError(ERROR_INVALID_PARAMETER);
00584
return FALSE;
00585 }
00586
00587
00588
00589
00590
00591
if (pMachineName)
00592 {
00593 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
00594 }
00595
else
00596 pszMachineName =
NULL;
00597
00598
00599
00600
00601
00602 rc = rc &&
ConvertToAnsi(pProfileName, &pszProfileName,
TRUE);
00603
00604
00605
00606
00607
00608 rc = rc &&
InternalInstallColorProfile(pszMachineName, pszProfileName);
00609
00610
00611
00612
00613
00614
if (pszProfileName)
00615 {
00616
MemFree(pszProfileName);
00617 }
00618
00619
if (pszMachineName)
00620 {
00621
MemFree(pszMachineName);
00622 }
00623
00624
return rc;
00625 }
00626
00627
00628
#endif // ! UNICODE
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
#ifdef UNICODE // Windows NT versions
00651
00652
BOOL WINAPI
00653
UninstallColorProfileA(
00654 PCSTR pMachineName,
00655 PCSTR pProfileName,
00656 BOOL bDelete
00657 )
00658 {
00659 PWSTR pwszMachineName =
NULL;
00660 PWSTR pwszProfileName =
NULL;
00661
BOOL rc =
TRUE;
00662
00663
TRACEAPI((__TEXT(
"UninstallColorProfileA\n")));
00664
00665
00666
00667
00668
00669
if (!pProfileName)
00670 {
00671
WARNING((__TEXT(
"Invalid parameter to UninstallColorProfile\n")));
00672 SetLastError(ERROR_INVALID_PARAMETER);
00673
return FALSE;
00674 }
00675
00676
00677
00678
00679
00680
if (pMachineName)
00681 {
00682 rc =
ConvertToUnicode(pMachineName, &pwszMachineName, TRUE);
00683 }
00684
else
00685 pwszMachineName =
NULL;
00686
00687
00688
00689
00690
00691 rc = rc &&
ConvertToUnicode(pProfileName, &pwszProfileName, TRUE);
00692
00693
00694
00695
00696
00697 rc = rc &&
InternalUninstallColorProfile(pwszMachineName, pwszProfileName,
00698 bDelete);
00699
00700
00701
00702
00703
00704
if (pwszProfileName)
00705 {
00706
MemFree(pwszProfileName);
00707 }
00708
00709
if (pwszMachineName)
00710 {
00711
MemFree(pwszMachineName);
00712 }
00713
00714
return rc;
00715 }
00716
00717
BOOL WINAPI
00718
UninstallColorProfileW(
00719 PCWSTR pMachineName,
00720 PCWSTR pProfileName,
00721 BOOL bDelete
00722 )
00723 {
00724
TRACEAPI((__TEXT(
"UninstallColorProfileW\n")));
00725
00726
00727
00728
00729
00730
return InternalUninstallColorProfile(pMachineName, pProfileName, bDelete);
00731 }
00732
00733
00734
#else // Windows 95 versions
00735
00736
BOOL WINAPI
00737 UninstallColorProfileA(
00738 PCSTR pMachineName,
00739 PCSTR pProfileName,
00740 BOOL bDelete
00741 )
00742 {
00743
TRACEAPI((__TEXT(
"UninstallColorProfileA\n")));
00744
00745
00746
00747
00748
00749
return InternalUninstallColorProfile(pMachineName, pProfileName, bDelete);
00750 }
00751
00752
00753
BOOL WINAPI
00754 UninstallColorProfileW(
00755 PCWSTR pMachineName,
00756 PCWSTR pProfileName,
00757 BOOL bDelete
00758 )
00759 {
00760 PSTR pszMachineName =
NULL;
00761 PSTR pszProfileName =
NULL;
00762
BOOL rc =
TRUE;
00763
00764
TRACEAPI((__TEXT(
"UninstallColorProfileW\n")));
00765
00766
00767
00768
00769
00770
if (!pProfileName)
00771 {
00772
WARNING((__TEXT(
"Invalid parameter to UninstallColorProfile\n")));
00773 SetLastError(ERROR_INVALID_PARAMETER);
00774
return FALSE;
00775 }
00776
00777
00778
00779
00780
00781
if (pMachineName)
00782 {
00783 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
00784 }
00785
else
00786 pszMachineName =
NULL;
00787
00788
00789
00790
00791
00792 rc = rc &&
ConvertToAnsi(pProfileName, &pszProfileName,
TRUE);
00793
00794
00795
00796
00797
00798 rc = rc &&
InternalUninstallColorProfile(pszMachineName, pszProfileName,
00799 bDelete);
00800
00801
00802
00803
00804
00805
if (pszProfileName)
00806 {
00807
MemFree(pszProfileName);
00808 }
00809
00810
if (pszMachineName)
00811 {
00812
MemFree(pszMachineName);
00813 }
00814
00815
return rc;
00816 }
00817
00818
00819
#endif // ! UNICODE
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
#ifdef UNICODE // Windows NT versions
00843
00844
BOOL WINAPI
00845
AssociateColorProfileWithDeviceA(
00846 PCSTR pMachineName,
00847 PCSTR pProfileName,
00848 PCSTR pDeviceName
00849 )
00850 {
00851 PWSTR pwszMachineName =
NULL;
00852 PWSTR pwszProfileName =
NULL;
00853 PWSTR pwszDeviceName =
NULL;
00854
BOOL rc =
TRUE;
00855
00856
TRACEAPI((__TEXT(
"AssociateColorProfileWithDeviceA\n")));
00857
00858
00859
00860
00861
00862
if (! pProfileName ||
00863 ! pDeviceName)
00864 {
00865
WARNING((__TEXT(
"Invalid parameter to AssociateColorProfileWithDevice\n")));
00866 SetLastError(ERROR_INVALID_PARAMETER);
00867
return FALSE;
00868 }
00869
00870
00871
00872
00873
00874
if (pMachineName)
00875 {
00876 rc =
ConvertToUnicode(pMachineName, &pwszMachineName, TRUE);
00877 }
00878
else
00879 pwszMachineName =
NULL;
00880
00881
00882
00883
00884
00885 rc = rc &&
ConvertToUnicode(pProfileName, &pwszProfileName, TRUE);
00886
00887
00888
00889
00890
00891 rc = rc &&
ConvertToUnicode(pDeviceName, &pwszDeviceName, TRUE);
00892
00893
00894
00895
00896
00897 rc = rc &&
InternalAssociateColorProfileWithDevice(pwszMachineName,
00898 pwszProfileName, pwszDeviceName);
00899
00900
00901
00902
00903
00904
if (pwszProfileName)
00905 {
00906
MemFree(pwszProfileName);
00907 }
00908
00909
if (pwszMachineName)
00910 {
00911
MemFree(pwszMachineName);
00912 }
00913
00914
if (pwszDeviceName)
00915 {
00916
MemFree(pwszDeviceName);
00917 }
00918
00919
return rc;
00920 }
00921
00922
00923
BOOL WINAPI
00924
AssociateColorProfileWithDeviceW(
00925 PCWSTR pMachineName,
00926 PCWSTR pProfileName,
00927 PCWSTR pDeviceName
00928 )
00929 {
00930
TRACEAPI((__TEXT(
"AssociateColorProfileWithDeviceW\n")));
00931
00932
00933
00934
00935
00936
return InternalAssociateColorProfileWithDevice(pMachineName,
00937 pProfileName, pDeviceName);
00938 }
00939
00940
00941
#else // Windows 95 versions
00942
00943
BOOL WINAPI
00944 AssociateColorProfileWithDeviceA(
00945 PCSTR pMachineName,
00946 PCSTR pProfileName,
00947 PCSTR pDeviceName
00948 )
00949 {
00950
TRACEAPI((__TEXT(
"AssociateColorProfileWithDeviceA\n")));
00951
00952
00953
00954
00955
00956
return InternalAssociateColorProfileWithDevice(pMachineName,
00957 pProfileName, pDeviceName);
00958 }
00959
00960
00961
BOOL WINAPI
00962 AssociateColorProfileWithDeviceW(
00963 PCWSTR pMachineName,
00964 PCWSTR pProfileName,
00965 PCWSTR pDeviceName
00966 )
00967 {
00968 PSTR pszMachineName =
NULL;
00969 PSTR pszProfileName =
NULL;
00970 PSTR pszDeviceName =
NULL;
00971
BOOL rc =
TRUE;
00972
00973
TRACEAPI((__TEXT(
"AssociateColorProfileWithDeviceW\n")));
00974
00975
00976
00977
00978
00979
if (! pProfileName ||
00980 ! pDeviceName)
00981 {
00982
WARNING((__TEXT(
"Invalid parameter to AssociateColorProfileWithDevice\n")));
00983 SetLastError(ERROR_INVALID_PARAMETER);
00984
return FALSE;
00985 }
00986
00987
00988
00989
00990
00991
if (pMachineName)
00992 {
00993 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
00994 }
00995
else
00996 pszMachineName =
NULL;
00997
00998
00999
01000
01001
01002 rc = rc &&
ConvertToAnsi(pProfileName, &pszProfileName,
TRUE);
01003
01004
01005
01006
01007
01008 rc = rc &&
ConvertToAnsi(pDeviceName, &pszDeviceName,
TRUE);
01009
01010
01011
01012
01013
01014 rc = rc &&
InternalAssociateColorProfileWithDevice(pszMachineName,
01015 pszProfileName, pszDeviceName);
01016
01017
01018
01019
01020
01021
if (pszProfileName)
01022 {
01023
MemFree(pszProfileName);
01024 }
01025
01026
if (pszMachineName)
01027 {
01028
MemFree(pszMachineName);
01029 }
01030
01031
if (pszDeviceName)
01032 {
01033
MemFree(pszDeviceName);
01034 }
01035
01036
return rc;
01037 }
01038
01039
#endif // ! UNICODE
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
#ifdef UNICODE // Windows NT versions
01063
01064
BOOL WINAPI
01065
DisassociateColorProfileFromDeviceA(
01066 PCSTR pMachineName,
01067 PCSTR pProfileName,
01068 PCSTR pDeviceName
01069 )
01070 {
01071 PWSTR pwszMachineName =
NULL;
01072 PWSTR pwszProfileName =
NULL;
01073 PWSTR pwszDeviceName =
NULL;
01074
BOOL rc =
TRUE;
01075
01076
TRACEAPI((__TEXT(
"DisassociateColorProfileWithDeviceA\n")));
01077
01078
01079
01080
01081
01082
if (! pProfileName ||
01083 ! pDeviceName)
01084 {
01085
WARNING((__TEXT(
"Invalid parameter to DisassociateColorProfileFromDevice\n")));
01086 SetLastError(ERROR_INVALID_PARAMETER);
01087
return FALSE;
01088 }
01089
01090
01091
01092
01093
01094
if (pMachineName)
01095 {
01096 rc =
ConvertToUnicode(pMachineName, &pwszMachineName, TRUE);
01097 }
01098
else
01099 pwszMachineName =
NULL;
01100
01101
01102
01103
01104
01105 rc = rc &&
ConvertToUnicode(pProfileName, &pwszProfileName, TRUE);
01106
01107
01108
01109
01110
01111 rc = rc &&
ConvertToUnicode(pDeviceName, &pwszDeviceName, TRUE);
01112
01113
01114
01115
01116
01117 rc = rc &&
InternalDisassociateColorProfileFromDevice(pwszMachineName,
01118 pwszProfileName, pwszDeviceName);
01119
01120
01121
01122
01123
01124
if (pwszProfileName)
01125 {
01126
MemFree(pwszProfileName);
01127 }
01128
01129
if (pwszMachineName)
01130 {
01131
MemFree(pwszMachineName);
01132 }
01133
01134
if (pwszDeviceName)
01135 {
01136
MemFree(pwszDeviceName);
01137 }
01138
01139
return rc;
01140 }
01141
01142
01143
BOOL WINAPI
01144
DisassociateColorProfileFromDeviceW(
01145 PCWSTR pMachineName,
01146 PCWSTR pProfileName,
01147 PCWSTR pDeviceName
01148 )
01149 {
01150
TRACEAPI((__TEXT(
"DisassociateColorProfileWithDeviceW\n")));
01151
01152
01153
01154
01155
01156
return InternalDisassociateColorProfileFromDevice(pMachineName,
01157 pProfileName, pDeviceName);
01158 }
01159
01160
01161
#else // Windows 95 versions
01162
01163
BOOL WINAPI
01164 DisassociateColorProfileFromDeviceA(
01165 PCSTR pMachineName,
01166 PCSTR pProfileName,
01167 PCSTR pDeviceName
01168 )
01169 {
01170
TRACEAPI((__TEXT(
"DisassociateColorProfileWithDeviceA\n")));
01171
01172
01173
01174
01175
01176
return InternalDisassociateColorProfileFromDevice(pMachineName,
01177 pProfileName, pDeviceName);
01178 }
01179
01180
01181
BOOL WINAPI
01182 DisassociateColorProfileFromDeviceW(
01183 PCWSTR pMachineName,
01184 PCWSTR pProfileName,
01185 PCWSTR pDeviceName
01186 )
01187 {
01188 PSTR pszMachineName =
NULL;
01189 PSTR pszProfileName =
NULL;
01190 PSTR pszDeviceName =
NULL;
01191
BOOL rc =
TRUE;
01192
01193
TRACEAPI((__TEXT(
"DisassociateColorProfileWithDeviceW\n")));
01194
01195
01196
01197
01198
01199
if (! pProfileName ||
01200 ! pDeviceName)
01201 {
01202
WARNING((__TEXT(
"Invalid parameter to AssociateColorProfileWithDevice\n")));
01203 SetLastError(ERROR_INVALID_PARAMETER);
01204
return FALSE;
01205 }
01206
01207
01208
01209
01210
01211
if (pMachineName)
01212 {
01213 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
01214 }
01215
else
01216 pszMachineName =
NULL;
01217
01218
01219
01220
01221
01222 rc = rc &&
ConvertToAnsi(pProfileName, &pszProfileName,
TRUE);
01223
01224
01225
01226
01227
01228 rc = rc &&
ConvertToAnsi(pDeviceName, &pszDeviceName,
TRUE);
01229
01230
01231
01232
01233
01234 rc = rc &&
InternalDisassociateColorProfileFromDevice(pszMachineName,
01235 pszProfileName, pszDeviceName);
01236
01237
01238
01239
01240
01241
if (pszProfileName)
01242 {
01243
MemFree(pszProfileName);
01244 }
01245
01246
if (pszMachineName)
01247 {
01248
MemFree(pszMachineName);
01249 }
01250
01251
if (pszDeviceName)
01252 {
01253
MemFree(pszDeviceName);
01254 }
01255
01256
return rc;
01257 }
01258
01259
#endif // ! UNICODE
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
#ifdef UNICODE // Windows NT versions
01288
01289
BOOL WINAPI
01290
EnumColorProfilesA(
01291 PCSTR pMachineName,
01292 PENUMTYPEA pEnumRecord,
01293 PBYTE pBuffer,
01294 PDWORD pdwSize,
01295 PDWORD pnProfiles
01296 )
01297 {
01298 PWSTR pwszMachineName =
NULL;
01299 PWSTR pwszDeviceName =
NULL;
01300 PSTR pAnsiDeviceName =
NULL;
01301 PWSTR pwBuffer =
NULL;
01302 PWSTR pwTempBuffer =
NULL;
01303
DWORD dwSize;
01304
DWORD dwSizeOfStruct;
01305
DWORD dwVersion;
01306
BOOL rc =
TRUE;
01307
01308
TRACEAPI((__TEXT(
"EnumColorProfilesA\n")));
01309
01310
01311
01312
01313
01314
if (! pdwSize ||
01315 IsBadWritePtr(pdwSize,
sizeof(DWORD)) ||
01316 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)) ||
01317 ! pEnumRecord ||
01318 IsBadReadPtr(pEnumRecord,
sizeof(DWORD)*3))
01319 {
01320 ParameterError_EnumColorProfilesA:
01321
WARNING((__TEXT(
"Invalid parameter to EnumColorProfiles\n")));
01322 SetLastError(ERROR_INVALID_PARAMETER);
01323
return FALSE;
01324 }
01325
01326
01327
01328
01329
01330 dwSizeOfStruct = pEnumRecord->dwSize;
01331 dwVersion = pEnumRecord->dwVersion;
01332
01333
if (dwVersion >= ENUM_TYPE_VERSION)
01334 {
01335
if (dwSizeOfStruct <
sizeof(ENUMTYPE))
01336
goto ParameterError_EnumColorProfilesA;
01337 }
01338
else if (dwVersion == 0x0200)
01339 {
01340
if (dwSizeOfStruct <
sizeof(ENUMTYPE)-
sizeof(
DWORD))
01341
goto ParameterError_EnumColorProfilesA;
01342
01343
01344
01345
01346
01347
if (pEnumRecord->dwFields & ET_DEVICECLASS)
01348
goto ParameterError_EnumColorProfilesA;
01349
01350
WARNING((__TEXT(
"Old version ENUMTYPE to EnumColorProfiles\n")));
01351 }
01352
else
01353 {
01354
goto ParameterError_EnumColorProfilesA;
01355 }
01356
01357
if (IsBadReadPtr(pEnumRecord, dwSizeOfStruct))
01358 {
01359
goto ParameterError_EnumColorProfilesA;
01360 }
01361
01362
01363
01364
01365
01366
if (pMachineName)
01367 {
01368 rc =
ConvertToUnicode(pMachineName, &pwszMachineName, TRUE);
01369 }
01370
else
01371 pwszMachineName =
NULL;
01372
01373
01374
01375
01376
01377
if (pEnumRecord->dwFields & ET_DEVICENAME)
01378 {
01379
if (! pEnumRecord->pDeviceName)
01380 {
01381
WARNING((__TEXT(
"Invalid parameter to EnumColorProfiles\n")));
01382 SetLastError(ERROR_INVALID_PARAMETER);
01383 rc =
FALSE;
01384
goto EndEnumColorProfilesA;
01385 }
01386
01387
01388
01389
01390
01391 pAnsiDeviceName = (PSTR)pEnumRecord->pDeviceName;
01392 rc = rc &&
ConvertToUnicode(pAnsiDeviceName, &pwszDeviceName, TRUE);
01393 pEnumRecord->pDeviceName = (PSTR) pwszDeviceName;
01394 }
01395
01396 dwSize = *pdwSize *
sizeof(WCHAR);
01397
01398
01399
01400
01401
01402
if (pBuffer && dwSize)
01403 {
01404 pwBuffer =
MemAlloc(dwSize);
01405
if (! pwBuffer)
01406 {
01407
WARNING((__TEXT(
"Error allocating memory for Unicode buffer\n")));
01408 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01409 rc =
FALSE;
01410
goto EndEnumColorProfilesA;
01411 }
01412 }
01413
01414
01415
01416
01417
01418 rc = rc &&
InternalEnumColorProfiles(pwszMachineName,
01419 (PENUMTYPEW)pEnumRecord, (PBYTE)pwBuffer, &dwSize, pnProfiles);
01420
01421
if (pwBuffer && rc)
01422 {
01423 pwTempBuffer = pwBuffer;
01424
while (*pwTempBuffer)
01425 {
01426 rc = rc &&
ConvertToAnsi(pwTempBuffer, (PSTR *)&pBuffer, FALSE);
01427 pwTempBuffer += lstrlenW(pwTempBuffer) + 1;
01428 pBuffer += (lstrlenA((PSTR)pBuffer) + 1) *
sizeof(
char);
01429 }
01430
01431 *((PSTR)pBuffer) =
'\0';
01432 }
01433
01434 *pdwSize = dwSize /
sizeof(WCHAR);
01435
01436 EndEnumColorProfilesA:
01437
if (pwszMachineName)
01438 {
01439
MemFree(pwszMachineName);
01440 }
01441
if (pAnsiDeviceName)
01442 {
01443
ASSERT(pEnumRecord->pDeviceName != NULL);
01444
01445
MemFree((PBYTE)pEnumRecord->pDeviceName);
01446 pEnumRecord->pDeviceName = (PCSTR)pAnsiDeviceName;
01447 }
01448
if (pwBuffer)
01449 {
01450
MemFree(pwBuffer);
01451 }
01452
01453
return rc;
01454 }
01455
01456
01457
BOOL WINAPI
01458
EnumColorProfilesW(
01459 PCWSTR pMachineName,
01460 PENUMTYPEW pEnumRecord,
01461 PBYTE pBuffer,
01462 PDWORD pdwSize,
01463 PDWORD pnProfiles
01464 )
01465 {
01466
TRACEAPI((__TEXT(
"EnumColorProfilesW\n")));
01467
01468
01469
01470
01471
01472
return InternalEnumColorProfiles(pMachineName, pEnumRecord,
01473 pBuffer, pdwSize, pnProfiles);
01474 }
01475
01476
#else // Windows 95 versions
01477
01478
BOOL WINAPI
01479 EnumColorProfilesA(
01480 PCSTR pMachineName,
01481 PENUMTYPEA pEnumRecord,
01482 PBYTE pBuffer,
01483 PDWORD pdwSize,
01484 PDWORD pnProfiles
01485 )
01486 {
01487
TRACEAPI((__TEXT(
"EnumColorProfilesA\n")));
01488
01489
01490
01491
01492
01493
return InternalEnumColorProfiles(pMachineName, pEnumRecord,
01494 pBuffer, pdwSize, pnProfiles);
01495 }
01496
01497
01498
BOOL WINAPI
01499 EnumColorProfilesW(
01500 PCWSTR pMachineName,
01501 PENUMTYPEW pEnumRecord,
01502 PBYTE pBuffer,
01503 PDWORD pdwSize,
01504 PDWORD pnProfiles
01505 )
01506 {
01507 PSTR pszMachineName =
NULL;
01508 PSTR pszDeviceName =
NULL;
01509 PWSTR pUnicodeDeviceName =
NULL;
01510 PSTR pszBuffer =
NULL;
01511 PSTR pszTempBuffer =
NULL;
01512
DWORD dwSize;
01513
DWORD dwSizeOfStruct;
01514
DWORD dwVersion;
01515
BOOL rc =
TRUE;
01516
01517
TRACEAPI((__TEXT(
"EnumColorProfilesW\n")));
01518
01519
01520
01521
01522
01523
if (! pdwSize ||
01524 IsBadWritePtr(pdwSize,
sizeof(
DWORD)) ||
01525 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)) ||
01526 ! pEnumRecord ||
01527 IsBadReadPtr(pEnumRecord,
sizeof(
DWORD)*3))
01528 {
01529 ParameterError_EnumColorProfilesW:
01530
WARNING((__TEXT(
"Invalid parameter to EnumColorProfiles\n")));
01531 SetLastError(ERROR_INVALID_PARAMETER);
01532
return FALSE;
01533 }
01534
01535
01536
01537
01538
01539 dwSizeOfStruct = pEnumRecord->dwSize;
01540 dwVersion = pEnumRecord->dwVersion;
01541
01542
if (dwVersion >= ENUM_TYPE_VERSION)
01543 {
01544
if (dwSizeOfStruct <
sizeof(ENUMTYPE))
01545
goto ParameterError_EnumColorProfilesW;
01546 }
01547
else if (dwVersion == 0x0200)
01548 {
01549
if (dwSizeOfStruct <
sizeof(ENUMTYPE)-
sizeof(
DWORD))
01550
goto ParameterError_EnumColorProfilesW;
01551
01552
01553
01554
01555
01556
if (pEnumRecord->dwFields & ET_DEVICECLASS)
01557
goto ParameterError_EnumColorProfilesW;
01558
01559
WARNING((__TEXT(
"Old version ENUMTYPE to EnumColorProfiles\n")));
01560 }
01561
else
01562 {
01563
goto ParameterError_EnumColorProfilesW;
01564 }
01565
01566
if (IsBadReadPtr(pEnumRecord, dwSizeOfStruct))
01567 {
01568
goto ParameterError_EnumColorProfilesW;
01569 }
01570
01571
01572
01573
01574
01575
if (pMachineName)
01576 {
01577 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
01578 }
01579
01580
01581
01582
01583
01584
if (pEnumRecord->dwFields & ET_DEVICENAME)
01585 {
01586
if (! pEnumRecord->pDeviceName)
01587 {
01588
WARNING((__TEXT(
"Invalid parameter to EnumColorProfiles\n")));
01589 SetLastError(ERROR_INVALID_PARAMETER);
01590
goto EndEnumColorProfilesW;
01591 }
01592
01593
01594
01595
01596
01597 pUnicodeDeviceName = (PWSTR)pEnumRecord->pDeviceName;
01598 rc = rc &&
ConvertToAnsi(pUnicodeDeviceName, &pszDeviceName,
TRUE);
01599 pEnumRecord->pDeviceName = (PCWSTR) pszDeviceName;
01600 }
01601
01602 dwSize = *pdwSize /
sizeof(WCHAR);
01603
01604
01605
01606
01607
01608
if (pBuffer && dwSize)
01609 {
01610 pszBuffer =
MemAlloc(dwSize);
01611
if (! pszBuffer)
01612 {
01613
WARNING((__TEXT(
"Error allocating memory for Ansi buffer\n")));
01614 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01615 rc =
FALSE;
01616
goto EndEnumColorProfilesW;
01617 }
01618 }
01619
01620
01621
01622
01623
01624 rc = rc &&
InternalEnumColorProfiles(pszMachineName,
01625 (PENUMTYPEA)pEnumRecord, (
PBYTE)pszBuffer, &dwSize, pnProfiles);
01626
01627
if (pszBuffer && rc)
01628 {
01629 pszTempBuffer = pszBuffer;
01630
while (*pszTempBuffer)
01631 {
01632 rc = rc &&
ConvertToUnicode(pszTempBuffer, (PWSTR *)&pBuffer,
FALSE);
01633 pszTempBuffer += lstrlenA(pszTempBuffer) + 1;
01634 pBuffer += (lstrlenW((PWSTR)pBuffer) + 1) *
sizeof(WCHAR);
01635 }
01636
01637 *((PWSTR)pBuffer) =
'\0';
01638 }
01639 *pdwSize = dwSize *
sizeof(WCHAR);
01640
01641 EndEnumColorProfilesW:
01642
if (pszMachineName)
01643 {
01644
MemFree(pszMachineName);
01645 }
01646
if (pUnicodeDeviceName)
01647 {
01648
ASSERT(pEnumRecord->pDeviceName !=
NULL);
01649
01650
MemFree((PSTR)pEnumRecord->pDeviceName);
01651 pEnumRecord->pDeviceName = (PCWSTR)pUnicodeDeviceName;
01652 }
01653
if (pszBuffer)
01654 {
01655
MemFree(pszBuffer);
01656 }
01657
01658
return rc;
01659 }
01660
01661
#endif // ! UNICODE
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
#ifdef UNICODE // Windows NT versions
01685
01686
BOOL WINAPI
01687
SetStandardColorSpaceProfileA(
01688 PCSTR pMachineName,
01689 DWORD dwSCS,
01690 PCSTR pProfileName
01691 )
01692 {
01693 PWSTR pwszMachineName =
NULL;
01694 PWSTR pwszProfileName =
NULL;
01695
BOOL rc =
TRUE;
01696
01697
TRACEAPI((__TEXT(
"SetStandardColorSpaceProfileA\n")));
01698
01699
01700
01701
01702
01703
if (! pProfileName)
01704 {
01705
WARNING((__TEXT(
"Invalid parameter to SetStandardColorSpaceProfile\n")));
01706 SetLastError(ERROR_INVALID_PARAMETER);
01707
return FALSE;
01708 }
01709
01710
01711
01712
01713
01714
if (pMachineName)
01715 {
01716 rc =
ConvertToUnicode(pMachineName, &pwszMachineName, TRUE);
01717 }
01718
else
01719 pwszMachineName =
NULL;
01720
01721
01722
01723
01724
01725 rc = rc &&
ConvertToUnicode(pProfileName, &pwszProfileName, TRUE);
01726
01727
01728
01729
01730
01731 rc = rc &&
InternalSetSCSProfile(pwszMachineName, dwSCS, pwszProfileName);
01732
01733
01734
01735
01736
01737
if (pwszProfileName)
01738 {
01739
MemFree(pwszProfileName);
01740 }
01741
01742
if (pwszMachineName)
01743 {
01744
MemFree(pwszMachineName);
01745 }
01746
01747
return rc;
01748 }
01749
01750
BOOL WINAPI
01751
SetStandardColorSpaceProfileW(
01752 PCWSTR pMachineName,
01753 DWORD dwSCS,
01754 PCWSTR pProfileName
01755 )
01756 {
01757
TRACEAPI((__TEXT(
"SetStandardColorSpaceProfileW\n")));
01758
01759
01760
01761
01762
01763
return InternalSetSCSProfile(pMachineName, dwSCS, pProfileName);
01764 }
01765
01766
#else // Windows 95 versions
01767
01768
BOOL WINAPI
01769 SetStandardColorSpaceProfileA(
01770 PCSTR pMachineName,
01771 DWORD dwSCS,
01772 PCSTR pProfileName
01773 )
01774 {
01775
TRACEAPI((__TEXT(
"SetStandardColorSpaceProfileA\n")));
01776
01777
01778
01779
01780
01781
return InternalSetSCSProfile(pMachineName, dwSCS, pProfileName);
01782 }
01783
01784
BOOL WINAPI
01785 SetStandardColorSpaceProfileW(
01786 PCWSTR pMachineName,
01787 DWORD dwSCS,
01788 PCWSTR pProfileName
01789 )
01790 {
01791 PSTR pszMachineName =
NULL;
01792 PSTR pszProfileName =
NULL;
01793
BOOL rc =
TRUE;
01794
01795
TRACEAPI((__TEXT(
"SetStandardColorSpaceProfileW\n")));
01796
01797
01798
01799
01800
01801
if (! pProfileName)
01802 {
01803
WARNING((__TEXT(
"Invalid parameter to SetStandardColorSpaceProfile\n")));
01804 SetLastError(ERROR_INVALID_PARAMETER);
01805
return FALSE;
01806 }
01807
01808
01809
01810
01811
01812
if (pMachineName)
01813 {
01814 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
01815 }
01816
else
01817 pszMachineName =
NULL;
01818
01819
01820
01821
01822
01823 rc = rc &&
ConvertToAnsi(pProfileName, &pszProfileName,
TRUE);
01824
01825
01826
01827
01828
01829 rc = rc &&
InternalSetSCSProfile(pszMachineName, dwSCS, pszProfileName);
01830
01831
01832
01833
01834
01835
if (pszProfileName)
01836 {
01837
MemFree(pszProfileName);
01838 }
01839
01840
if (pszMachineName)
01841 {
01842
MemFree(pszMachineName);
01843 }
01844
01845
return rc;
01846 }
01847
01848
#endif // ! UNICODE
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
#ifdef UNICODE // Windows NT versions
01874
01875
BOOL WINAPI
01876
GetStandardColorSpaceProfileA(
01877 PCSTR pMachineName,
01878 DWORD dwSCS,
01879 PSTR pBuffer,
01880 PDWORD pdwSize
01881 )
01882 {
01883 PWSTR pwszMachineName =
NULL;
01884 PWSTR pwBuffer =
NULL;
01885
DWORD dwSize;
01886
BOOL rc =
TRUE;
01887
01888
TRACEAPI((__TEXT(
"GetStandardColorSpaceProfileA\n")));
01889
01890
01891
01892
01893
01894
if (! pdwSize ||
01895 IsBadWritePtr(pdwSize,
sizeof(DWORD)) ||
01896 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)))
01897 {
01898
WARNING((__TEXT(
"Invalid parameter to GetStandardColorSpaceProfile\n")));
01899 SetLastError(ERROR_INVALID_PARAMETER);
01900
return FALSE;
01901 }
01902
01903
01904
01905
01906
01907
if (pMachineName)
01908 {
01909 rc =
ConvertToUnicode(pMachineName, &pwszMachineName, TRUE);
01910 }
01911
else
01912 pwszMachineName =
NULL;
01913
01914 dwSize = *pdwSize *
sizeof(WCHAR);
01915
01916
01917
01918
01919
01920
if (pBuffer && dwSize)
01921 {
01922 pwBuffer = (PWSTR)
MemAlloc(dwSize);
01923
if (! pwBuffer)
01924 {
01925
WARNING((__TEXT(
"Error allocating memory for Unicode string\n")));
01926 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01927 rc =
FALSE;
01928
goto EndGetSCSProfileA;
01929 }
01930 }
01931
01932 rc = rc &&
InternalGetSCSProfile(pwszMachineName, dwSCS, pwBuffer, &dwSize);
01933
01934 *pdwSize = dwSize /
sizeof(WCHAR);
01935
01936
01937
01938
01939
01940
if (pwBuffer)
01941 {
01942 rc = rc &&
ConvertToAnsi(pwBuffer, &pBuffer, FALSE);
01943 }
01944
01945 EndGetSCSProfileA:
01946
if (pwszMachineName)
01947 {
01948
MemFree(pwszMachineName);
01949 }
01950
01951
if (pwBuffer)
01952 {
01953
MemFree(pwBuffer);
01954 }
01955
01956
return rc;
01957 }
01958
01959
BOOL WINAPI
01960
GetStandardColorSpaceProfileW(
01961 PCWSTR pMachineName,
01962 DWORD dwSCS,
01963 PWSTR pBuffer,
01964 PDWORD pdwSize
01965 )
01966 {
01967
TRACEAPI((__TEXT(
"GetStandardColorSpaceProfileW\n")));
01968
01969
01970
01971
01972
01973
return InternalGetSCSProfile(pMachineName, dwSCS, pBuffer, pdwSize);
01974 }
01975
01976
#else // Windows 95 versions
01977
01978
BOOL WINAPI
01979 GetStandardColorSpaceProfileA(
01980 PCSTR pMachineName,
01981 DWORD dwSCS,
01982 PSTR pBuffer,
01983 PDWORD pdwSize
01984 )
01985 {
01986
TRACEAPI((__TEXT(
"GetStandardColorSpaceProfileA\n")));
01987
01988
01989
01990
01991
01992
return InternalGetSCSProfile(pMachineName, dwSCS, pBuffer, pdwSize);
01993 }
01994
01995
BOOL WINAPI
01996 GetStandardColorSpaceProfileW(
01997 PCWSTR pMachineName,
01998 DWORD dwSCS,
01999 PWSTR pBuffer,
02000 PDWORD pdwSize
02001 )
02002 {
02003 PSTR pszMachineName =
NULL;
02004 PSTR pszBuffer =
NULL;
02005
DWORD dwSize;
02006
BOOL rc =
TRUE;
02007
02008
TRACEAPI((__TEXT(
"GetStandardColorSpaceProfileW\n")));
02009
02010
02011
02012
02013
02014
if (! pdwSize ||
02015 IsBadWritePtr(pdwSize,
sizeof(
DWORD)) ||
02016 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)))
02017 {
02018
WARNING((__TEXT(
"Invalid parameter to GetStandardColorSpaceProfile\n")));
02019 SetLastError(ERROR_INVALID_PARAMETER);
02020
return FALSE;
02021 }
02022
02023
02024
02025
02026
02027
if (pMachineName)
02028 {
02029 rc =
ConvertToAnsi(pMachineName, &pszMachineName,
TRUE);
02030 }
02031
else
02032 pszMachineName =
NULL;
02033
02034 dwSize = *pdwSize /
sizeof(WCHAR);
02035
02036
02037
02038
02039
02040
if (pBuffer && dwSize)
02041 {
02042 pszBuffer = (PSTR)
MemAlloc(dwSize);
02043
if (! pBuffer)
02044 {
02045
WARNING((__TEXT(
"Error allocating memory for Ansi string\n")));
02046 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02047 rc =
FALSE;
02048
goto EndGetSCSProfileW;
02049 }
02050 }
02051
02052 rc = rc &&
InternalGetSCSProfile(pszMachineName, dwSCS, pszBuffer, &dwSize);
02053
02054 *pdwSize = dwSize *
sizeof(WCHAR);
02055
02056
02057
02058
02059
02060
if (pszBuffer)
02061 {
02062 rc = rc &&
ConvertToUnicode(pszBuffer, &pBuffer,
FALSE);
02063 }
02064
02065 EndGetSCSProfileW:
02066
if (pszMachineName)
02067 {
02068
MemFree(pszMachineName);
02069 }
02070
02071
if (pszBuffer)
02072 {
02073
MemFree(pszBuffer);
02074 }
02075
02076
return rc;
02077 }
02078
02079
#endif // ! UNICODE
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
DWORD WINAPI
02102 GenerateCopyFilePaths(
02103 LPCWSTR pszPrinterName,
02104 LPCWSTR pszDirectory,
02105 LPBYTE pSplClientInfo,
02106 DWORD dwLevel,
02107 LPWSTR pszSourceDir,
02108 LPDWORD pcchSourceDirSize,
02109 LPWSTR pszTargetDir,
02110 LPDWORD pcchTargetDirSize,
02111 DWORD dwFlags
02112 )
02113 {
02114
TRACEAPI((__TEXT(
"GenerateCopyFilePaths\n")));
02115
return ERROR_SUCCESS;
02116 }
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
BOOL WINAPI
02142 SpoolerCopyFileEvent(
02143 LPWSTR pszPrinterName,
02144 LPWSTR pszKey,
02145 DWORD dwCopyFileEvent
02146 )
02147 {
02148 PTSTR pProfileList, pTemp, pBuffer;
02149
DWORD dwSize;
02150
BOOL bRc =
FALSE;
02151 TCHAR szPath[
MAX_PATH];
02152
02153
TRACEAPI((__TEXT(
"SpoolerCopyFileEvent\n")));
02154
02155
switch (dwCopyFileEvent)
02156 {
02157
case COPYFILE_EVENT_SET_PRINTER_DATAEX:
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
TERSE((__TEXT(
"SetPrinterDataEx event\n")));
02170
02171
case COPYFILE_EVENT_ADD_PRINTER_CONNECTION:
02172
case COPYFILE_EVENT_FILES_CHANGED:
02173
02174
02175
02176
02177
02178
02179
02180
#ifdef DBG
02181
if (dwCopyFileEvent == COPYFILE_EVENT_ADD_PRINTER_CONNECTION)
02182 {
02183
WARNING((__TEXT(
"AddPrinterConnection Event\n")));
02184 }
02185
else if (dwCopyFileEvent == COPYFILE_EVENT_FILES_CHANGED)
02186 {
02187
WARNING((__TEXT(
"FilesChanged Event\n")));
02188 }
02189
#endif
02190
02191 dwSize = 0;
02192
if (
GetDeviceData((PTSTR)pszPrinterName, CLASS_PRINTER,
DEVICE_PROFILE_DATA,
02193 (PVOID *)&pProfileList, &dwSize,
TRUE))
02194 {
02195 dwSize =
sizeof(szPath);
02196
if (
InternalGetColorDirectory(
NULL, szPath, &dwSize))
02197 {
02198 lstrcat(szPath,
gszBackslash);
02199 pBuffer = szPath + lstrlen(szPath);
02200 pTemp = pProfileList;
02201
while (*pTemp)
02202 {
02203 lstrcpy(pBuffer, pTemp);
02204 InstallColorProfile(
NULL, szPath);
02205 pTemp += lstrlen(pTemp) + 1;
02206 }
02207 }
02208
02209
MemFree(pProfileList);
02210 }
02211
break;
02212
02213
case COPYFILE_EVENT_DELETE_PRINTER:
02214
02215
02216
02217
02218
02219
02220
02221
TERSE((__TEXT(
"DeletePrinterDataEx Event\n")));
02222
02223 dwSize = 0;
02224
if (
GetDeviceData((PTSTR)pszPrinterName, CLASS_PRINTER,
DEVICE_PROFILE_DATA,
02225 (PVOID *)&pProfileList, &dwSize,
TRUE))
02226 {
02227 pTemp = pProfileList;
02228
while (*pTemp)
02229 {
02230 DisassociateColorProfileFromDevice(
NULL, pTemp, (PTSTR)pszPrinterName);
02231 pTemp += lstrlen(pTemp) + 1;
02232 }
02233
02234
MemFree(pProfileList);
02235 }
02236
break;
02237 }
02238
02239 bRc =
TRUE;
02240
02241
return bRc;
02242 }
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
BOOL
02273 InternalGetColorDirectory(
02274 LPCTSTR pMachineName,
02275 PTSTR pBuffer,
02276 DWORD *pdwSize
02277 )
02278 {
02279
DWORD dwBufLen = *pdwSize;
02280
BOOL rc =
FALSE;
02281
02282
02283
02284
02285
02286
#if !defined(_WIN95_)
02287
02288
DWORD dwNeeded;
02289
02290
if (!pBuffer && pdwSize && !IsBadWritePtr(pdwSize,
sizeof(
DWORD)))
02291 {
02292 *pdwSize = 0;
02293 }
02294
02295
if (GetPrinterDriverDirectory((PTSTR)pMachineName,
NULL, 1, (
PBYTE)pBuffer,
02296 *pdwSize, pdwSize))
02297 {
02298
02299
02300
02301
02302
02303
02304 PWSTR pDriverDir;
02305
02306 pDriverDir =
GetFilenameFromPath(pBuffer);
02307
02308
ASSERT (pDriverDir !=
NULL);
02309
02310 *pdwSize -= lstrlen(pDriverDir) *
sizeof(WCHAR);
02311
02312 *pDriverDir =
'\0';
02313
02314
02315
02316
02317
02318 dwNeeded = *pdwSize + lstrlen(
gszColorDir) *
sizeof(WCHAR);
02319
if (pBuffer[lstrlen(pBuffer) - 1] !=
'\\')
02320 {
02321 dwNeeded +=
sizeof(WCHAR);
02322 }
02323
02324
02325
02326
02327
02328 *pdwSize = dwNeeded;
02329
02330
02331
02332
02333
02334
if (dwNeeded <= dwBufLen)
02335 {
02336
if (pBuffer[lstrlen(pBuffer) - 1] !=
'\\')
02337 {
02338 lstrcat(pBuffer,
gszBackslash);
02339 }
02340
02341 lstrcat(pBuffer,
gszColorDir);
02342
02343 rc =
TRUE;
02344 }
02345
else
02346 {
02347
WARNING((__TEXT(
"Input buffer to GetColorDirectory not big enough\n")));
02348 SetLastError(ERROR_INSUFFICIENT_BUFFER);
02349 }
02350 }
02351
else if (GetLastError() == ERROR_INVALID_USER_BUFFER)
02352 {
02353
02354
02355
02356
02357 SetLastError(ERROR_INSUFFICIENT_BUFFER);
02358 }
02359
else if (GetLastError() == RPC_S_SERVER_UNAVAILABLE)
02360 {
02361 TCHAR achTempPath[
MAX_PATH * 2];
02362
02363
02364
02365
02366
02367
if (GetSystemDirectory(achTempPath,
MAX_PATH) != 0)
02368 {
02369 _tcscat(achTempPath,TEXT(
"\\spool\\drivers\\color"));
02370
02371 *pdwSize = wcslen(achTempPath) + 1;
02372
02373
if (pBuffer && (*pdwSize <= dwBufLen))
02374 {
02375 _tcscpy(pBuffer,achTempPath);
02376
02377 rc =
TRUE;
02378 }
02379
else
02380 {
02381
WARNING((__TEXT(
"Input buffer to GetColorDirectory not big enough\n")));
02382 SetLastError(ERROR_INSUFFICIENT_BUFFER);
02383 }
02384 }
02385 }
02386
02387
#else
02388
02389 HKEY hkSetup;
02390
DWORD dwErr;
02391
02392
02393
02394
02395
02396
if (pMachineName)
02397 {
02398
WARNING((__TEXT(
"Remote color directory query, failing...\n")));
02399 SetLastError(ERROR_INVALID_PARAMETER);
02400
return FALSE;
02401 }
02402
02403
02404
02405
02406
02407
02408
02409
02410
if ((dwErr = RegOpenKey(HKEY_LOCAL_MACHINE, gszSetupPath, &hkSetup)) == ERROR_SUCCESS)
02411 {
02412
if ((dwErr = RegQueryValueEx(hkSetup, gszICMDir, 0,
NULL, (
PBYTE)pBuffer,
02413 pdwSize)) == ERROR_SUCCESS)
02414 {
02415 rc =
TRUE;
02416 }
02417 RegCloseKey(hkSetup);
02418 }
02419
02420
if (!rc)
02421 {
02422
02423
02424
02425
02426
if (dwErr == ERROR_MORE_DATA)
02427 {
02428 dwErr = ERROR_INSUFFICIENT_BUFFER;
02429 }
02430
02431
WARNING((__TEXT(
"Error getting color directory: %d\n"), dwErr));
02432 SetLastError(dwErr);
02433 }
02434
02435
02436
02437
02438
02439
02440
if (pBuffer ==
NULL && rc)
02441 {
02442 SetLastError(ERROR_INSUFFICIENT_BUFFER);
02443 rc =
FALSE;
02444 }
02445
02446
#endif // !defined(_WIN95_)
02447
02448
return rc;
02449 }
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
BOOL
02475 InternalInstallColorProfile(
02476 LPCTSTR pMachineName,
02477 LPCTSTR pProfileName
02478 )
02479 {
02480 PROFILEHEADER header;
02481
REGDATA regData;
02482 HKEY hkICM =
NULL;
02483 HKEY hkDevice =
NULL;
02484
DWORD dwSize;
02485
DWORD dwErr;
02486
BOOL rc =
FALSE;
02487 PTSTR pFilename;
02488 TCHAR szDest[
MAX_PATH];
02489 TCHAR szClass[5];
02490
BOOL FileExist;
02491
BOOL RegExist;
02492
02493
02494
02495
02496
02497
if (!pProfileName)
02498 {
02499
WARNING((__TEXT(
"Invalid parameter to InstallColorProfile\n")));
02500 SetLastError(ERROR_INVALID_PARAMETER);
02501
return FALSE;
02502 }
02503
02504
02505
02506
02507
02508
if (pMachineName)
02509 {
02510
WARNING((__TEXT(
"Remote install attempted, failing...\n")));
02511 SetLastError(ERROR_INVALID_PARAMETER);
02512
return FALSE;
02513 }
02514
02515
02516
02517
02518
02519 pFilename =
GetFilenameFromPath((PTSTR)pProfileName);
02520
if (! pFilename)
02521 {
02522
WARNING((__TEXT(
"Could not parse file name from profile path %s\n"), pProfileName));
02523 SetLastError(ERROR_INVALID_PARAMETER);
02524
goto EndInstallColorProfile;
02525 }
02526
02527
02528
02529
02530
02531
if (!
GetProfileClassString(pProfileName, szClass, &header))
02532 {
02533
WARNING((__TEXT(
"Installing invalid profile %s\n"), pProfileName));
02534 SetLastError(ERROR_INVALID_PROFILE);
02535
goto EndInstallColorProfile;
02536 }
02537
02538
02539
02540
02541
02542
if (((dwErr = RegCreateKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM)) != ERROR_SUCCESS) ||
02543 ((dwErr = RegCreateKey(hkICM, szClass, &hkDevice)) != ERROR_SUCCESS))
02544 {
02545
WARNING((__TEXT(
"Cannot open ICM\\device branch of registry: %d\n"), dwErr));
02546 SetLastError(dwErr);
02547
goto EndInstallColorProfile;
02548 }
02549
02550
02551
02552
02553
02554
02555
02556
02557 dwSize =
sizeof(szDest);
02558
02559
02560
02561
02562
02563
if (!
InternalGetColorDirectory(
NULL, szDest, &dwSize))
02564 {
02565
WARNING((__TEXT(
"Could not get color directory\n")));
02566
goto EndInstallColorProfile;
02567 }
02568
02569
02570
02571
02572
02573
02574 CreateDirectory(szDest,
NULL);
02575
02576
if (szDest[lstrlen(szDest) - 1] !=
'\\')
02577 {
02578 lstrcat(szDest,
gszBackslash);
02579 }
02580 lstrcat(szDest, pFilename);
02581
02582
02583
02584
02585
02586
02587 dwSize =
sizeof(
REGDATA);
02588
02589 FileExist = GetFileAttributes(szDest) != (
DWORD)-1;
02590 RegExist = RegQueryValueEx(hkDevice, pFilename, 0,
NULL, (
PBYTE)®Data, &dwSize) == ERROR_SUCCESS;
02591
02592
02593
02594
02595
02596
02597
if (!FileExist && !CopyFile(pProfileName, szDest,
FALSE))
02598 {
02599
WARNING((__TEXT(
"Could not copy profile %s to color directory\n"), pProfileName));
02600
goto EndInstallColorProfile;
02601 }
02602
02603
02604
02605
02606
02607
if(!RegExist)
02608 {
02609 regData.dwRefCount = 0;
02610 regData.dwManuID = FIX_ENDIAN(header.phManufacturer);
02611 regData.dwModelID = FIX_ENDIAN(header.phModel);
02612
if ((dwErr = RegSetValueEx(hkDevice, pFilename, 0, REG_BINARY,
02613 (
PBYTE)®Data,
sizeof(
REGDATA))) != ERROR_SUCCESS)
02614 {
02615
WARNING((__TEXT(
"Could not set registry data to install profile %s: %d\n"), pFilename, dwErr));
02616 SetLastError(dwErr);
02617
goto EndInstallColorProfile;
02618 }
02619 }
02620
02621 rc =
TRUE;
02622
02623 EndInstallColorProfile:
02624
if (hkICM)
02625 {
02626 RegCloseKey(hkICM);
02627 }
02628
if (hkDevice)
02629 {
02630 RegCloseKey(hkDevice);
02631 }
02632
02633
return rc;
02634 }
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
BOOL
02664 InternalUninstallColorProfile(
02665 LPCTSTR pMachineName,
02666 LPCTSTR pProfileName,
02667 BOOL bDelete
02668 )
02669 {
02670
REGDATA regData;
02671 HKEY hkICM =
NULL;
02672 HKEY hkDevice =
NULL;
02673
DWORD dwSize;
02674
DWORD dwErr;
02675
BOOL rc =
FALSE;
02676 PTSTR pFilename;
02677 TCHAR szColorPath[
MAX_PATH];
02678 TCHAR szClass[5];
02679
02680
02681
02682
02683
02684
if (!pProfileName)
02685 {
02686
WARNING((__TEXT(
"Invalid parameter to UninstallColorProfile\n")));
02687 SetLastError(ERROR_INVALID_PARAMETER);
02688
return FALSE;
02689 }
02690
02691
02692
02693
02694
02695
if (pMachineName !=
NULL)
02696 {
02697
WARNING((__TEXT(
"Remote uninstall attempted, failing...\n")));
02698 SetLastError(ERROR_NOT_SUPPORTED);
02699
return FALSE;
02700 }
02701
02702
02703
02704
02705
02706 pFilename =
GetFilenameFromPath((PTSTR)pProfileName);
02707
if (! pFilename)
02708 {
02709
WARNING((__TEXT(
"Could not parse file name from profile path\n"), pProfileName));
02710 SetLastError(ERROR_INVALID_PARAMETER);
02711
goto EndUninstallColorProfile;
02712 }
02713
02714
02715
02716
02717
02718 dwSize =
sizeof(szColorPath);
02719
if (!
InternalGetColorDirectory(
NULL, szColorPath, &dwSize))
02720 {
02721
WARNING((__TEXT(
"Could not get color directory\n")));
02722
goto EndUninstallColorProfile;
02723 }
02724
02725
if (szColorPath[lstrlen(szColorPath) - 1] !=
'\\')
02726 {
02727 lstrcat(szColorPath,
gszBackslash);
02728 }
02729 lstrcat(szColorPath, pFilename);
02730
02731
02732
02733
02734
02735
if (!
GetProfileClassString(szColorPath, szClass,
NULL))
02736 {
02737
WARNING((__TEXT(
"Installing invalid profile\n")));
02738 SetLastError(ERROR_INVALID_PROFILE);
02739
goto EndUninstallColorProfile;
02740 }
02741
02742
02743
02744
02745
02746
if (((dwErr = RegOpenKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM)) != ERROR_SUCCESS) ||
02747 ((dwErr = RegOpenKey(hkICM, szClass, &hkDevice)) != ERROR_SUCCESS))
02748 {
02749
WARNING((__TEXT(
"Cannot open ICM\\device branch of registry: %d\n"), dwErr));
02750 SetLastError(dwErr);
02751
goto EndUninstallColorProfile;
02752 }
02753
02754
02755
02756
02757
02758 dwSize =
sizeof(
REGDATA);
02759
if ((dwErr = RegQueryValueEx(hkDevice, pFilename, 0,
NULL, (
PBYTE)®Data,
02760 &dwSize)) != ERROR_SUCCESS)
02761 {
02762
WARNING((__TEXT(
"Trying to uninstall a profile that is not installed %s: %d\n"), pFilename, dwErr));
02763 SetLastError(dwErr);
02764
goto EndUninstallColorProfile;
02765 }
02766
02767
if (regData.dwRefCount != 0)
02768 {
02769
WARNING((__TEXT(
"Trying to uninstall profile %s whose refcount is %d\n"),
02770 pFilename, regData.dwRefCount));
02771
goto EndUninstallColorProfile;
02772 }
02773
02774
if ((dwErr = RegDeleteValue(hkDevice, pFilename)) != ERROR_SUCCESS)
02775 {
02776
WARNING((__TEXT(
"Error deleting profile %s from registry: %d\n"), pFilename, dwErr));
02777 SetLastError(dwErr);
02778
goto EndUninstallColorProfile;
02779 }
02780
02781
02782
02783
02784
02785
if (bDelete)
02786 {
02787
02788
02789
02790
02791
if (! DeleteFile(szColorPath))
02792 {
02793
WARNING((__TEXT(
"Error deleting profile %s: %d\n"), szColorPath, GetLastError()));
02794
goto EndUninstallColorProfile;
02795 }
02796 }
02797
02798 rc =
TRUE;
02799
02800 EndUninstallColorProfile:
02801
if (hkICM)
02802 {
02803 RegCloseKey(hkICM);
02804 }
02805
if (hkDevice)
02806 {
02807 RegCloseKey(hkDevice);
02808 }
02809
02810
return rc;
02811 }
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
BOOL
02838 InternalAssociateColorProfileWithDevice(
02839 LPCTSTR pMachineName,
02840 LPCTSTR pProfileName,
02841 LPCTSTR pDeviceName
02842 )
02843 {
02844 PROFILEHEADER header;
02845
REGDATA regData;
02846 HKEY hkICM =
NULL;
02847 HKEY hkDevice =
NULL;
02848
DWORD dwSize;
02849
DWORD dwNewSize;
02850
DWORD dwErr;
02851
BOOL rc =
FALSE;
02852 PTSTR pFilename;
02853 PTSTR pProfileList =
NULL;
02854 TCHAR szColorPath[
MAX_PATH];
02855 TCHAR szClass[5];
02856
BOOL bFirstProfile =
FALSE;
02857
DWORD dwDeviceClass;
02858
02859
02860
02861
02862
02863
if (! pProfileName ||
02864 ! pDeviceName)
02865 {
02866
WARNING((__TEXT(
"Invalid parameter to AssociateColorProfileWithDevice\n")));
02867 SetLastError(ERROR_INVALID_PARAMETER);
02868
return FALSE;
02869 }
02870
02871
02872
02873
02874
02875
if (pMachineName !=
NULL)
02876 {
02877
WARNING((__TEXT(
"Remote profile association attempted, failing...\n")));
02878 SetLastError(ERROR_NOT_SUPPORTED);
02879
return FALSE;
02880 }
02881
02882
02883
02884
02885
02886 pFilename =
GetFilenameFromPath((PTSTR)pProfileName);
02887
if (! pFilename)
02888 {
02889
WARNING((__TEXT(
"Could not parse file name from profile path %s\n"), pProfileName));
02890 SetLastError(ERROR_INVALID_PARAMETER);
02891
goto EndAssociateProfileWithDevice;
02892 }
02893
02894
02895
02896
02897
02898 dwSize =
sizeof(szColorPath);
02899
if (!
InternalGetColorDirectory(
NULL, szColorPath, &dwSize))
02900 {
02901
WARNING((__TEXT(
"Could not get color directory\n")));
02902
goto EndAssociateProfileWithDevice;
02903 }
02904
02905
if (szColorPath[lstrlen(szColorPath) - 1] !=
'\\')
02906 {
02907 lstrcat(szColorPath,
gszBackslash);
02908 }
02909 lstrcat(szColorPath, pFilename);
02910
02911
02912
02913
02914
02915
if (!
GetProfileClassString(szColorPath, szClass, &header))
02916 {
02917
WARNING((__TEXT(
"Installing invalid profile %s\n"), szColorPath));
02918 SetLastError(ERROR_INVALID_PROFILE);
02919
goto EndAssociateProfileWithDevice;
02920 }
02921
02922
02923
02924
02925
02926
if (((dwErr = RegOpenKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM)) != ERROR_SUCCESS) ||
02927 ((dwErr = RegOpenKey(hkICM, szClass, &hkDevice)) != ERROR_SUCCESS))
02928 {
02929
WARNING((__TEXT(
"Cannot open ICM\\device branch of registry: %d\n"), dwErr));
02930 SetLastError(dwErr);
02931
goto EndAssociateProfileWithDevice;
02932 }
02933
02934
02935
02936
02937
02938 dwSize =
sizeof(
REGDATA);
02939
if ((dwErr = RegQueryValueEx(hkDevice, pFilename, 0,
NULL, (
PBYTE)®Data,
02940 &dwSize)) != ERROR_SUCCESS)
02941 {
02942
WARNING((__TEXT(
"Trying to associate a profile that is not installed %s: %d\n"), pFilename, dwErr));
02943 SetLastError(dwErr);
02944
goto EndAssociateProfileWithDevice;
02945 }
02946
02947
02948
02949
02950
if ((dwDeviceClass = header.phClass) == CLASS_MONITOR)
02951 {
02952
02953
02954
02955 dwDeviceClass = CLASS_COLORSPACE;
02956 }
02957
02958
02959
02960
02961
02962 dwSize = 0;
02963
if (!
GetDeviceData(pDeviceName, dwDeviceClass,
DEVICE_PROFILE_DATA,
02964 (PVOID *)&pProfileList, &dwSize,
TRUE))
02965 {
02966 pProfileList =
NULL;
02967 }
02968
02969
02970
02971
02972
02973
02974
if (pProfileList &&
02975
IsStringInMultiSz(pProfileList, pFilename) ==
TRUE)
02976 {
02977 rc =
TRUE;
02978
goto EndAssociateProfileWithDevice;
02979 }
02980
02981
if (dwSize <=
sizeof(TCHAR))
02982 {
02983 bFirstProfile =
TRUE;
02984 }
02985
02986
02987
02988
02989
02990
02991
if (dwSize > 0)
02992 {
02993
02994
02995
02996
02997
02998 PTSTR pTemp;
02999
03000 dwNewSize = dwSize + (lstrlen(pFilename) + 1) *
sizeof(TCHAR);
03001
03002 pTemp =
MemReAlloc(pProfileList, dwNewSize);
03003
if (! pTemp)
03004 {
03005
WARNING((__TEXT(
"Error reallocating pProfileList\n")));
03006 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03007
goto EndAssociateProfileWithDevice;
03008 }
03009
else
03010 pProfileList = pTemp;
03011 }
03012
else
03013 {
03014
03015
03016
03017
03018
03019
03020 dwSize =
sizeof(TCHAR);
03021
03022 dwNewSize = dwSize + (lstrlen(pFilename) + 1) *
sizeof(TCHAR);
03023 pProfileList =
MemAlloc(dwNewSize);
03024
if (! pProfileList)
03025 {
03026
WARNING((__TEXT(
"Error allocating pProfileList\n")));
03027 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03028
goto EndAssociateProfileWithDevice;
03029 }
03030 }
03031 {
03032 PTSTR pPtr;
03033
03034 pPtr = (PTSTR)((
PBYTE)pProfileList + dwSize -
sizeof(TCHAR));
03035 lstrcpy(pPtr, pFilename);
03036 pPtr = (PTSTR)((
PBYTE)pProfileList + dwNewSize -
sizeof(TCHAR));
03037 *pPtr =
'\0';
03038 }
03039
03040
03041
03042
03043
03044
if (!
SetDeviceData(pDeviceName, dwDeviceClass,
DEVICE_PROFILE_DATA,
03045 pProfileList, dwNewSize))
03046 {
03047
WARNING((__TEXT(
"Error setting device profile data for %s\n"), pDeviceName));
03048
goto EndAssociateProfileWithDevice;
03049 }
03050
03051
03052
03053
03054
03055 regData.dwRefCount++;
03056
if ((dwErr = RegSetValueEx(hkDevice, pFilename, 0, REG_BINARY,
03057 (
PBYTE)®Data,
sizeof(
REGDATA))) != ERROR_SUCCESS)
03058 {
03059
ERR((__TEXT(
"Could not set registry data for profile %s: %d\n"), pFilename, dwErr));
03060 SetLastError(dwErr);
03061
goto EndAssociateProfileWithDevice;
03062 }
03063
03064
#if !defined(_WIN95_)
03065
03066
if (bFirstProfile)
03067 {
03068
ChangeICMSetting(pMachineName, pDeviceName, ICM_ON);
03069 }
03070
03071
#endif
03072
03073 rc =
TRUE;
03074
03075 EndAssociateProfileWithDevice:
03076
if (hkICM)
03077 {
03078 RegCloseKey(hkICM);
03079 }
03080
if (hkDevice)
03081 {
03082 RegCloseKey(hkDevice);
03083 }
03084
if (pProfileList)
03085 {
03086
MemFree(pProfileList);
03087 }
03088
03089
return rc;
03090 }
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
BOOL
03118 InternalDisassociateColorProfileFromDevice(
03119 LPCTSTR pMachineName,
03120 LPCTSTR pProfileName,
03121 LPCTSTR pDeviceName
03122 )
03123 {
03124 PROFILEHEADER header;
03125
REGDATA regData;
03126 HKEY hkICM =
NULL;
03127 HKEY hkDevice =
NULL;
03128
DWORD dwSize;
03129
DWORD dwNewSize;
03130
DWORD dwErr;
03131
BOOL rc =
FALSE;
03132 PTSTR pFilename;
03133 PTSTR pProfileList =
NULL;
03134 TCHAR szColorPath[
MAX_PATH];
03135 TCHAR szClass[5];
03136
BOOL bLastProfile =
FALSE;
03137
DWORD dwDeviceClass;
03138
03139
03140
03141
03142
03143
if (! pProfileName ||
03144 ! pDeviceName)
03145 {
03146
WARNING((__TEXT(
"Invalid parameter to DisassociateColorProfileFromDevice\n")));
03147 SetLastError(ERROR_INVALID_PARAMETER);
03148
return FALSE;
03149 }
03150
03151
03152
03153
03154
03155
if (pMachineName !=
NULL)
03156 {
03157
WARNING((__TEXT(
"Remote profile disassociation attempted, failing...\n")));
03158 SetLastError(ERROR_NOT_SUPPORTED);
03159
return FALSE;
03160 }
03161
03162
03163
03164
03165
03166 pFilename =
GetFilenameFromPath((PTSTR)pProfileName);
03167
if (! pFilename)
03168 {
03169
WARNING((__TEXT(
"Could not parse file name from profile path %s\n"), pProfileName));
03170 SetLastError(ERROR_INVALID_PARAMETER);
03171
goto EndDisassociateProfileWithDevice;
03172 }
03173
03174
03175
03176
03177
03178 dwSize =
sizeof(szColorPath);
03179
if (!
InternalGetColorDirectory(
NULL, szColorPath, &dwSize))
03180 {
03181
WARNING((__TEXT(
"Could not get color directory\n")));
03182
goto EndDisassociateProfileWithDevice;
03183 }
03184
03185
if (szColorPath[lstrlen(szColorPath) - 1] !=
'\\')
03186 {
03187 lstrcat(szColorPath,
gszBackslash);
03188 }
03189 lstrcat(szColorPath, pFilename);
03190
03191
03192
03193
03194
03195
if (!
GetProfileClassString(szColorPath, szClass, &header))
03196 {
03197
WARNING((__TEXT(
"Installing invalid profile %s\n"), szColorPath));
03198 SetLastError(ERROR_INVALID_PROFILE);
03199
goto EndDisassociateProfileWithDevice;
03200 }
03201
03202
03203
03204
03205
03206
if (((dwErr = RegOpenKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM)) != ERROR_SUCCESS) ||
03207 ((dwErr = RegOpenKey(hkICM, szClass, &hkDevice)) != ERROR_SUCCESS))
03208 {
03209
WARNING((__TEXT(
"Cannot open ICM\\device branch of registry: %d\n"), dwErr));
03210 SetLastError(dwErr);
03211
goto EndDisassociateProfileWithDevice;
03212 }
03213
03214
03215
03216
03217
03218 dwSize =
sizeof(
REGDATA);
03219
if ((dwErr = RegQueryValueEx(hkDevice, pFilename, 0,
NULL, (
PBYTE)®Data,
03220 &dwSize)) != ERROR_SUCCESS)
03221 {
03222
WARNING((__TEXT(
"Trying to disassociate a profile that is not installed %s: %d\n"), pFilename, dwErr));
03223 SetLastError(dwErr);
03224
goto EndDisassociateProfileWithDevice;
03225 }
03226
03227
03228
03229
03230
if ((dwDeviceClass = header.phClass) == CLASS_MONITOR)
03231 {
03232
03233
03234
03235 dwDeviceClass = CLASS_COLORSPACE;
03236 }
03237
03238
03239
03240
03241
03242 dwSize = 0;
03243
if (!
GetDeviceData(pDeviceName, dwDeviceClass,
DEVICE_PROFILE_DATA,
03244 (PVOID *)&pProfileList, &dwSize,
TRUE))
03245 {
03246 pProfileList =
NULL;
03247 }
03248
03249
03250
03251
03252
03253
if (! pProfileList ||
03254 !
IsStringInMultiSz(pProfileList, pFilename))
03255 {
03256
WARNING((__TEXT(
"Trying to disassociate a profile that is not associated %s\n"), pFilename));
03257 SetLastError(ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE);
03258
goto EndDisassociateProfileWithDevice;
03259 }
03260
03261
03262
03263
03264
03265
03266 dwNewSize =
RemoveStringFromMultiSz(pProfileList, pFilename, dwSize);
03267
03268
03269
03270
03271
03272
if (!
SetDeviceData(pDeviceName, dwDeviceClass,
DEVICE_PROFILE_DATA,
03273 pProfileList, dwNewSize))
03274 {
03275
WARNING((__TEXT(
"Error setting device profile data for %s\n"), pDeviceName));
03276
goto EndDisassociateProfileWithDevice;
03277 }
03278
03279
if (dwNewSize <=
sizeof(TCHAR))
03280 {
03281 bLastProfile =
TRUE;
03282 }
03283
03284
03285
03286
03287
03288 regData.dwRefCount--;
03289
if ((dwErr = RegSetValueEx(hkDevice, pFilename, 0, REG_BINARY,
03290 (
PBYTE)®Data,
sizeof(
REGDATA))) != ERROR_SUCCESS)
03291 {
03292
ERR((__TEXT(
"Could not set registry data for profile %s: %d\n"), pFilename, dwErr));
03293 SetLastError(dwErr);
03294
goto EndDisassociateProfileWithDevice;
03295 }
03296
03297
#if !defined(_WIN95_)
03298
03299
if (bLastProfile)
03300 {
03301
ChangeICMSetting(pMachineName, pDeviceName, ICM_OFF);
03302 }
03303
03304
#endif
03305
03306 rc =
TRUE;
03307
03308 EndDisassociateProfileWithDevice:
03309
if (hkICM)
03310 {
03311 RegCloseKey(hkICM);
03312 }
03313
if (hkDevice)
03314 {
03315 RegCloseKey(hkDevice);
03316 }
03317
if (pProfileList)
03318 {
03319
MemFree(pProfileList);
03320 }
03321
03322
return rc;
03323 }
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
BOOL
03356 InternalEnumColorProfiles(
03357 LPCTSTR pMachineName,
03358 PENUMTYPE pEnumRecord,
03359 PBYTE pBuffer,
03360 PDWORD pdwSize,
03361 PDWORD pnProfiles
03362 )
03363 {
03364
REGDATA regData;
03365 HKEY hkICM =
NULL;
03366 HKEY hkDevice =
NULL;
03367 PTSTR pProfileList =
NULL;
03368 PTSTR pTempProfileList;
03369
DWORD dwSize;
03370
DWORD dwDataSize;
03371
DWORD dwInputSize;
03372
DWORD i, j;
03373
DWORD dwErr;
03374
BOOL rc =
FALSE;
03375 TCHAR szFullPath[
MAX_PATH];
03376 PTSTR pProfile;
03377
DWORD dwLen;
03378
DWORD bSkipMatch;
03379
MATCHTYPE match;
03380
PBYTE pBufferStart;
03381
DWORD dwSizeOfStruct;
03382
DWORD dwVersion;
03383
03384
03385
03386
03387
03388
if (! pdwSize ||
03389 IsBadWritePtr(pdwSize,
sizeof(
DWORD)) ||
03390 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)) ||
03391 (pnProfiles && IsBadWritePtr(pnProfiles,
sizeof(
DWORD))) ||
03392 ! pEnumRecord ||
03393 IsBadReadPtr(pEnumRecord,
sizeof(
DWORD)*3))
03394 {
03395 ParameterError_InternalEnumColorProfiles:
03396
WARNING((__TEXT(
"Invalid parameter to EnumColorProfiles\n")));
03397 SetLastError(ERROR_INVALID_PARAMETER);
03398
return FALSE;
03399 }
03400
03401
03402
03403
03404
03405 dwSizeOfStruct = pEnumRecord->dwSize;
03406 dwVersion = pEnumRecord->dwVersion;
03407
03408
if (dwVersion >= ENUM_TYPE_VERSION)
03409 {
03410
if (dwSizeOfStruct <
sizeof(ENUMTYPE))
03411
goto ParameterError_InternalEnumColorProfiles;
03412 }
03413
else if (dwVersion == 0x0200)
03414 {
03415
if (dwSizeOfStruct <
sizeof(ENUMTYPE)-
sizeof(
DWORD))
03416
goto ParameterError_InternalEnumColorProfiles;
03417
03418
03419
03420
03421
03422
if (pEnumRecord->dwFields & ET_DEVICECLASS)
03423
goto ParameterError_InternalEnumColorProfiles;
03424
03425
WARNING((__TEXT(
"Old version ENUMTYPE to InternalEnumColorProfiles\n")));
03426 }
03427
else
03428 {
03429
goto ParameterError_InternalEnumColorProfiles;
03430 }
03431
03432
if (IsBadReadPtr(pEnumRecord, dwSizeOfStruct))
03433 {
03434
goto ParameterError_InternalEnumColorProfiles;
03435 }
03436
03437
03438
03439
03440
03441
if (pMachineName !=
NULL)
03442 {
03443
WARNING((__TEXT(
"Remote profile enumeration attempted, failing...\n")));
03444 SetLastError(ERROR_NOT_SUPPORTED);
03445
return FALSE;
03446 }
03447
03448 dwInputSize = *pdwSize;
03449
03450
03451
03452
03453
03454 dwLen =
sizeof(szFullPath);
03455
if (!
InternalGetColorDirectory(
NULL, szFullPath, &dwLen))
03456 {
03457
WARNING((__TEXT(
"Error getting color directory\n")));
03458
return FALSE;
03459 }
03460
03461
if (szFullPath[lstrlen(szFullPath) - 1] !=
'\\')
03462 {
03463 lstrcat(szFullPath,
gszBackslash);
03464 }
03465 pProfile = &szFullPath[lstrlen(szFullPath)];
03466 dwLen = lstrlen(szFullPath) *
sizeof(TCHAR);
03467
03468
03469
03470
03471
03472 *pdwSize = 0;
03473
if (pnProfiles)
03474 *pnProfiles = 0;
03475
03476
if (pBuffer && dwInputSize >=
sizeof(TCHAR))
03477 {
03478 *((PTSTR)pBuffer) =
'\0';
03479 }
03480
03481
03482
03483
03484
03485
03486
if (pEnumRecord->dwFields & ET_DEVICENAME)
03487 {
03488
DWORD *pbSkipMatch = &bSkipMatch;
03489
DWORD dwDeviceClass;
03490
03491
if (! pEnumRecord->pDeviceName)
03492 {
03493
WARNING((__TEXT(
"Invalid parameter to EnumColorProfiles\n")));
03494 SetLastError(ERROR_INVALID_PARAMETER);
03495
goto EndEnumerateColorProfiles;
03496 }
03497
03498
03499
03500
03501
03502
03503
if (pEnumRecord->dwFields & ET_DEVICECLASS)
03504 {
03505 dwDeviceClass = pEnumRecord->dwDeviceClass;
03506 }
03507
else
03508 {
03509 dwDeviceClass = CLASS_COLORSPACE;
03510 }
03511
03512
03513
03514
03515
03516 dwSize =
sizeof(
DWORD);
03517
if (!
GetDeviceData(pEnumRecord->pDeviceName, dwDeviceClass,
DEVICE_PROFILE_ENUMMODE,
03518 (PVOID *)&pbSkipMatch, &dwSize,
FALSE))
03519 {
03520 bSkipMatch =
FALSE;
03521 }
03522
03523
03524
03525
03526
03527 dwSize = 0;
03528
if (!
GetDeviceData(pEnumRecord->pDeviceName, dwDeviceClass,
DEVICE_PROFILE_DATA,
03529 (PVOID *)&pProfileList, &dwSize,
TRUE))
03530 {
03531 pProfileList =
NULL;
03532 }
03533
03534
if(! pProfileList)
03535 {
03536
03537
03538
03539
03540 rc =
TRUE;
03541
if (pBuffer && dwInputSize >=
sizeof(TCHAR)*2)
03542 {
03543 *((PTSTR)pBuffer + 1) =
'\0';
03544 }
03545
goto EndEnumerateColorProfiles;
03546 }
03547
03548
03549
03550
03551
03552
03553
03554
03555 pBufferStart = pBuffer;
03556 pTempProfileList = pProfileList;
03557
03558
while (*pTempProfileList)
03559 {
03560 lstrcpy(pProfile, pTempProfileList);
03561
03562
if (bSkipMatch)
03563 {
03564 match =
EXACT_MATCH;
03565 }
03566
else
03567 {
03568 match =
DoesProfileMatchEnumRecord(szFullPath, pEnumRecord);
03569 }
03570
03571
if (match !=
NOMATCH)
03572 {
03573 *pdwSize += (lstrlen(pTempProfileList) + 1) *
sizeof(TCHAR);
03574
03575
03576
03577
03578
03579
03580
if (pBuffer && (*pdwSize < dwInputSize))
03581 {
03582
if (match ==
MATCH)
03583 {
03584 lstrcpy((PTSTR)pBuffer, pTempProfileList);
03585 }
03586
else
03587 {
03588
03589
03590
03591
03592
InsertInBuffer(pBufferStart, pBuffer, pTempProfileList);
03593 }
03594
03595 pBuffer += (lstrlen(pTempProfileList) + 1) *
sizeof(TCHAR);
03596 }
03597
03598
if (pnProfiles)
03599 (*pnProfiles)++;
03600 }
03601
03602 pTempProfileList += lstrlen(pTempProfileList) + 1;
03603 }
03604 }
03605
else
03606 {
03607
DWORD dwNumClasses;
03608 PTSTR *ppszEnumClasses;
03609 PTSTR pszEnumClassArray[2];
03610
03611
03612
03613
03614
03615
03616
if (pEnumRecord->dwFields & ET_DEVICECLASS)
03617 {
03618
03619
03620
03621
03622
03623 pszEnumClassArray[0] =
ConvertClassIdToClassString(pEnumRecord->dwDeviceClass);
03624 pszEnumClassArray[1] =
ConvertClassIdToClassString(CLASS_COLORSPACE);
03625
03626
if (!pszEnumClassArray[0] || !pszEnumClassArray[1])
03627 {
03628
WARNING((__TEXT(
"Invalid DeviceClass to EnumColorProfiles\n")));
03629 SetLastError(ERROR_INVALID_PARAMETER);
03630
goto EndEnumerateColorProfiles;
03631 }
03632
03633 ppszEnumClasses = pszEnumClassArray;
03634 dwNumClasses = 2;
03635 }
03636
else
03637 {
03638 ppszEnumClasses =
gpszClasses;
03639 dwNumClasses =
sizeof(
gpszClasses)/
sizeof(PTSTR);
03640 }
03641
03642
03643
03644
03645
03646
if ((dwErr = RegCreateKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM)) != ERROR_SUCCESS)
03647 {
03648
WARNING((__TEXT(
"Cannot open ICM branch of registry: %d\n"), dwErr));
03649 SetLastError(dwErr);
03650
goto EndEnumerateColorProfiles;
03651 }
03652
03653 pBufferStart = pBuffer;
03654
03655
for (i=0; i<dwNumClasses; i++,ppszEnumClasses++)
03656 {
03657
DWORD nValues;
03658
03659
if (RegOpenKey(hkICM, *ppszEnumClasses, &hkDevice) != ERROR_SUCCESS)
03660 {
03661
continue;
03662 }
03663
03664
if ((dwErr = RegQueryInfoKey(hkDevice,
NULL,
NULL, 0,
NULL,
NULL,
NULL,
03665 &nValues,
NULL,
NULL,
NULL,
NULL)) != ERROR_SUCCESS)
03666 {
03667
WARNING((__TEXT(
"Cannot count values in device branch of registry: %d\n"), dwErr));
03668 RegCloseKey(hkDevice);
03669 SetLastError(dwErr);
03670
goto EndEnumerateColorProfiles;
03671 }
03672
03673
03674
03675
03676
03677
03678
for (j=0; j<nValues; j++)
03679 {
03680 dwSize =
sizeof(szFullPath) - dwLen;
03681 dwDataSize =
sizeof(
REGDATA);
03682
if (RegEnumValue(hkDevice, j, pProfile, &dwSize, 0,
03683
NULL, (
PBYTE)®Data, &dwDataSize) == ERROR_SUCCESS)
03684 {
03685 match =
DoesProfileMatchEnumRecord(szFullPath, pEnumRecord);
03686
03687
if (match !=
NOMATCH)
03688 {
03689 *pdwSize += (lstrlen(pProfile) + 1) *
sizeof(TCHAR);
03690
if (pBuffer && (*pdwSize < dwInputSize))
03691 {
03692
if (match ==
MATCH)
03693 {
03694 lstrcpy((PTSTR)pBuffer, pProfile);
03695 }
03696
else
03697 {
03698
03699
03700
03701
03702
InsertInBuffer(pBufferStart, pBuffer, pProfile);
03703 }
03704
03705 pBuffer += (lstrlen(pProfile) + 1) *
sizeof(TCHAR);
03706 }
03707
03708
if (pnProfiles)
03709 (*pnProfiles)++;
03710 }
03711 }
03712 }
03713
03714 RegCloseKey(hkDevice);
03715 }
03716 }
03717
03718 *pdwSize +=
sizeof(TCHAR);
03719
03720
if (pBuffer && *pdwSize <= dwInputSize)
03721 {
03722 *((PTSTR)pBuffer) =
'\0';
03723 rc =
TRUE;
03724 }
03725
else
03726 {
03727 SetLastError(ERROR_INSUFFICIENT_BUFFER);
03728 }
03729
03730 EndEnumerateColorProfiles:
03731
03732
if (hkICM)
03733 {
03734 RegCloseKey(hkICM);
03735 }
03736
if (pProfileList)
03737 {
03738
MemFree(pProfileList);
03739 }
03740
03741
return rc;
03742 }
03743
03744
VOID
03745 InsertInBuffer(
03746 PBYTE pStart,
03747 PBYTE pEnd,
03748 PTSTR pString
03749 )
03750 {
03751
DWORD cnt = (lstrlen(pString) + 1) *
sizeof(TCHAR);
03752
03753
MyCopyMemory(pStart+cnt, pStart, (
DWORD)(pEnd - pStart));
03754
03755 lstrcpy((PTSTR)pStart, pString);
03756
03757
return;
03758 }
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
BOOL
03785 InternalSetSCSProfile(
03786 LPCTSTR pMachineName,
03787 DWORD dwSCS,
03788 LPCTSTR pProfileName
03789 )
03790 {
03791 HKEY hkICM =
NULL;
03792 HKEY hkRegProf =
NULL;
03793
DWORD dwSize;
03794
DWORD dwErr;
03795
BOOL rc =
FALSE;
03796 TCHAR szProfileID[5];
03797
03798
03799
03800
03801
03802
if (!pProfileName)
03803 {
03804
WARNING((__TEXT(
"Invalid parameter to SetStandardColorSpaceProfile\n")));
03805 SetLastError(ERROR_INVALID_PARAMETER);
03806
return FALSE;
03807 }
03808
03809
03810
03811
03812
03813
if (pMachineName !=
NULL)
03814 {
03815
WARNING((__TEXT(
"Remote SCS profile registration attempted, failing...\n")));
03816 SetLastError(ERROR_NOT_SUPPORTED);
03817
return FALSE;
03818 }
03819
03820 dwSize = (lstrlen(pProfileName) + 1) *
sizeof(TCHAR);
03821
03822
03823
03824
03825
03826
if (((dwErr = RegCreateKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM)) == ERROR_SUCCESS) &&
03827 ((dwErr = RegCreateKey(hkICM,
gszRegisteredProfiles, &hkRegProf))== ERROR_SUCCESS))
03828 {
03829
ConvertDwordToString(dwSCS, szProfileID);
03830
03831
if ((dwErr = RegSetValueEx(hkRegProf, szProfileID, 0, REG_SZ,
03832 (
PBYTE)pProfileName, dwSize)) == ERROR_SUCCESS)
03833 {
03834 rc =
TRUE;
03835 }
03836 }
03837
03838
if (hkICM)
03839 {
03840 RegCloseKey(hkICM);
03841 }
03842
03843
if (hkRegProf)
03844 {
03845 RegCloseKey(hkRegProf);
03846 }
03847
03848
if (!rc)
03849 {
03850
WARNING((__TEXT(
"InternalSetSCSProfile failed: %d\n"), dwErr));
03851 SetLastError(dwErr);
03852 }
03853
03854
return rc;
03855 }
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
BOOL
03884 InternalGetSCSProfile(
03885 LPCTSTR pMachineName,
03886 DWORD dwSCS,
03887 PTSTR pBuffer,
03888 PDWORD pdwSize
03889 )
03890 {
03891 HKEY hkICM =
NULL;
03892 HKEY hkRegProf =
NULL;
03893
DWORD dwErr;
03894
DWORD dwSize;
03895
BOOL rc =
FALSE;
03896 TCHAR szProfileID[5];
03897
03898
03899
03900
03901
03902
if (! pdwSize ||
03903 IsBadWritePtr(pdwSize,
sizeof(
DWORD)) ||
03904 (pBuffer && IsBadWritePtr(pBuffer, *pdwSize)))
03905 {
03906
WARNING((__TEXT(
"Invalid parameter to GetStandardColorSpaceProfile\n")));
03907 SetLastError(ERROR_INVALID_PARAMETER);
03908
return FALSE;
03909 }
03910
03911
03912
03913
03914
03915
if (pMachineName !=
NULL)
03916 {
03917
WARNING((__TEXT(
"Remote SCS profile query attempted, failing...\n")));
03918 SetLastError(ERROR_NOT_SUPPORTED);
03919
return FALSE;
03920 }
03921
03922 dwSize = *pdwSize;
03923
03924
03925
03926
03927
03928
if (((dwErr = RegOpenKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM)) == ERROR_SUCCESS) &&
03929 ((dwErr = RegOpenKey(hkICM,
gszRegisteredProfiles, &hkRegProf)) == ERROR_SUCCESS))
03930 {
03931
ConvertDwordToString(dwSCS, szProfileID);
03932
if ((dwErr = RegQueryValueEx(hkRegProf, szProfileID,
NULL,
NULL,
03933 (
PBYTE)pBuffer, pdwSize)) == ERROR_SUCCESS)
03934 {
03935 rc =
TRUE;
03936 }
03937 }
03938
03939
if (hkICM)
03940 {
03941 RegCloseKey(hkICM);
03942 }
03943
03944
if (hkRegProf)
03945 {
03946 RegCloseKey(hkRegProf);
03947 }
03948
03949
if (!rc && (dwSCS == LCS_sRGB || dwSCS == LCS_WINDOWS_COLOR_SPACE))
03950 {
03951 *pdwSize = dwSize;
03952 rc = GetColorDirectory(
NULL, pBuffer, pdwSize);
03953
if (!rc && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
03954 {
03955
return FALSE;
03956 }
03957
03958 *pdwSize += (lstrlen(
gszBackslash) + lstrlen(
gszsRGBProfile)) *
sizeof(TCHAR);
03959
03960
if (*pdwSize <= dwSize && pBuffer)
03961 {
03962 lstrcat(pBuffer,
gszBackslash);
03963 lstrcat(pBuffer,
gszsRGBProfile);
03964 rc =
TRUE;
03965 }
03966
else
03967 {
03968 dwErr = ERROR_INSUFFICIENT_BUFFER;
03969 }
03970 }
03971
03972
if (!rc)
03973 {
03974
WARNING((__TEXT(
"InternalGetSCSProfile failed: %d\n"), dwErr));
03975 SetLastError(dwErr);
03976 }
03977
03978
03979
03980
03981
03982
03983
if (pBuffer ==
NULL && rc)
03984 {
03985 SetLastError(ERROR_INSUFFICIENT_BUFFER);
03986 rc =
FALSE;
03987 }
03988
03989
return rc;
03990 }
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011
VOID
04012 ConvertDwordToString(
04013 DWORD dword,
04014 PTSTR pString
04015 )
04016 {
04017
int i;
04018
04019
for (i=0; i<4; i++)
04020 {
04021 pString[i] = (TCHAR)(((
char*)&dword)[3-i]);
04022 }
04023
04024 pString[4] =
'\0';
04025
04026
return;
04027 }
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044 PTSTR
04045 ConvertClassIdToClassString(
04046 DWORD dwClassId
04047 )
04048 {
04049
switch (dwClassId)
04050 {
04051
case CLASS_MONITOR:
04052
return (
gpszClasses[
INDEX_CLASS_MONITOR]);
04053
case CLASS_PRINTER:
04054
return (
gpszClasses[
INDEX_CLASS_PRINTER]);
04055
case CLASS_SCANNER:
04056
return (
gpszClasses[
INDEX_CLASS_SCANNER]);
04057
case CLASS_COLORSPACE:
04058
return (
gpszClasses[
INDEX_CLASS_COLORSPACE]);
04059
default:
04060
return NULL;
04061 }
04062 }
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
BOOL
04083 GetProfileClassString(
04084 LPCTSTR pProfileName,
04085 PTSTR pClass,
04086 PPROFILEHEADER pHeader
04087 )
04088 {
04089 PROFILEHEADER header;
04090 PROFILE prof;
04091 HPROFILE hProfile =
NULL;
04092
BOOL bValidProfile =
FALSE;
04093
BOOL rc =
FALSE;
04094
04095
04096
04097
04098
04099 prof.dwType = PROFILE_FILENAME;
04100 prof.pProfileData = (PVOID)pProfileName;
04101 prof.cbDataSize = (lstrlen(pProfileName) + 1) *
sizeof(TCHAR);
04102
04103 hProfile = OpenColorProfile(&prof, PROFILE_READ, FILE_SHARE_READ,
04104
OPEN_EXISTING);
04105
if (! hProfile)
04106 {
04107
WARNING((__TEXT(
"Error opening profile %s\n"), pProfileName));
04108
goto EndGetProfileClassString;
04109 }
04110
04111
04112
04113
04114
if (!
IsColorProfileValid(hProfile,&bValidProfile) || ! bValidProfile)
04115 {
04116
WARNING((__TEXT(
"Error invalid profile %s\n"), pProfileName));
04117
goto EndGetProfileClassString;
04118 }
04119
04120
04121
04122
04123
04124
if (! pHeader)
04125 {
04126 pHeader = &header;
04127 }
04128
04129
if (!
GetColorProfileHeader(hProfile, pHeader))
04130 {
04131
ERR((__TEXT(
"Error getting color profile header for %s\n"), pProfileName));
04132
goto EndGetProfileClassString;
04133 }
04134
ConvertDwordToString(pHeader->phClass, pClass);
04135
04136 rc=
TRUE;
04137
04138 EndGetProfileClassString:
04139
if (hProfile)
04140 {
04141
CloseColorProfile(hProfile);
04142 }
04143
04144
return rc;
04145 }
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164 PTSTR
04165 GetFilenameFromPath(
04166 PTSTR pPathName
04167 )
04168 {
04169
DWORD dwLen;
04170 PTSTR pPathNameStart = pPathName;
04171
04172 dwLen = lstrlen(pPathName);
04173
04174
if (dwLen == 0)
04175 {
04176
return NULL;
04177 }
04178
04179
04180
04181
04182
04183
04184 pPathName += dwLen;
04185
04186
04187
04188
04189
04190
04191
do
04192 {
04193 pPathName = CharPrev(pPathNameStart,pPathName);
04194
04195
if (*pPathName == TEXT(
'\\'))
04196 {
04197 pPathName = CharNext(pPathName);
04198
break;
04199 }
04200
04201
04202
04203
04204
04205 }
while (pPathNameStart < pPathName);
04206
04207
04208
04209
04210
04211
return *pPathName ? pPathName :
NULL;
04212 }
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
BOOL
04240 GetDeviceData(
04241 LPCTSTR pDeviceName,
04242 DWORD dwClass,
04243 DWORD dwDataType,
04244 PVOID *ppDeviceData,
04245 PDWORD pdwSize,
04246 BOOL bAllocate
04247 )
04248 {
04249
BOOL rc =
FALSE;
04250
04251
if (dwClass == CLASS_MONITOR ||
04252 dwClass == CLASS_PRINTER ||
04253 dwClass == CLASS_SCANNER)
04254 {
04255 rc =
IGetDeviceData(pDeviceName, dwClass, dwDataType, ppDeviceData, pdwSize, bAllocate);
04256 }
04257
else if (dwClass == CLASS_COLORSPACE)
04258 {
04259 rc =
IGetDeviceData(pDeviceName, CLASS_MONITOR, dwDataType, ppDeviceData, pdwSize, bAllocate) ||
04260
IGetDeviceData(pDeviceName, CLASS_PRINTER, dwDataType, ppDeviceData, pdwSize, bAllocate) ||
04261
IGetDeviceData(pDeviceName, CLASS_SCANNER, dwDataType, ppDeviceData, pdwSize, bAllocate);
04262 }
04263
04264
return rc;
04265 }
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
BOOL
04289 IGetDeviceData(
04290 LPCTSTR pDeviceName,
04291 DWORD dwClass,
04292 DWORD dwDataType,
04293 PVOID *ppDeviceData,
04294 PDWORD pdwSize,
04295 BOOL bAllocate
04296 )
04297 {
04298
PFNOPENDEVICE fnOpenDevice;
04299
PFNCLOSEDEVICE fnCloseDevice;
04300
PFNGETDEVICEDATA fnGetData;
04301 HANDLE hDevice;
04302
DWORD dwSize;
04303 LPTSTR pDataKey;
04304 LPTSTR pDataValue;
04305
BOOL rc =
FALSE;
04306
04307
04308
04309
04310
04311
switch (dwClass)
04312 {
04313
case CLASS_PRINTER:
04314 fnOpenDevice = (
PFNOPENDEVICE)
OpenPrtr;
04315 fnCloseDevice = (
PFNCLOSEDEVICE)
ClosePrtr;
04316 fnGetData = (
PFNGETDEVICEDATA)
GetPrtrData;
04317
break;
04318
04319
case CLASS_MONITOR:
04320 fnOpenDevice = (
PFNOPENDEVICE)
OpenMonitor;
04321 fnCloseDevice = (
PFNCLOSEDEVICE)
CloseMonitor;
04322 fnGetData = (
PFNGETDEVICEDATA)
GetMonitorData;
04323
break;
04324
04325
case CLASS_SCANNER:
04326 fnOpenDevice = (
PFNOPENDEVICE)
OpenScanner;
04327 fnCloseDevice = (
PFNCLOSEDEVICE)
CloseScanner;
04328 fnGetData = (
PFNGETDEVICEDATA)
GetScannerData;
04329
break;
04330
04331
default:
04332
return FALSE;
04333 }
04334
04335
04336
04337
04338
04339
switch (dwDataType)
04340 {
04341
case DEVICE_PROFILE_DATA:
04342
04343 pDataKey =
gszICMProfileListKey;
04344
04345
04346
04347
04348
04349
if (dwClass == CLASS_PRINTER)
04350 {
04351 pDataValue =
gszFiles;
04352 }
04353
else
04354 {
04355 pDataValue =
gszICMProfileListValue;
04356 }
04357
04358
break;
04359
04360
case DEVICE_PROFILE_ENUMMODE:
04361
04362 pDataKey =
gszICMDeviceDataKey;
04363 pDataValue =
gszICMProfileEnumMode;
04364
break;
04365
04366
default:
04367
return FALSE;
04368 }
04369
04370
04371
04372
04373
04374
if (! (*fnOpenDevice)((PTSTR)pDeviceName, &hDevice,
NULL))
04375 {
04376
return FALSE;
04377 }
04378
04379
if (bAllocate || (ppDeviceData ==
NULL))
04380 {
04381
DWORD retcode;
04382
04383
04384
04385
04386
04387
04388 dwSize = 0;
04389 retcode = (*fnGetData)(hDevice, pDataKey, pDataValue,
NULL,
NULL, 0, &dwSize);
04390
04391
if ((retcode != ERROR_SUCCESS) &&
04392 (retcode != ERROR_MORE_DATA))
04393 {
04394
VERBOSE((__TEXT(
"GetDeviceData failed for %s\n"), pDeviceName));
04395
goto EndGetDeviceData;
04396 }
04397
04398 *pdwSize = dwSize;
04399
04400
if (ppDeviceData ==
NULL)
04401 {
04402
04403
04404
04405
04406 rc =
TRUE;
04407
goto EndGetDeviceData;
04408 }
04409
else
04410 {
04411
04412
04413
04414
04415 *ppDeviceData =
MemAlloc(dwSize);
04416
if (! *ppDeviceData)
04417 {
04418
WARNING((__TEXT(
"Error allocating memory\n")));
04419 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
04420
goto EndGetDeviceData;
04421 }
04422 }
04423 }
04424
04425
04426
04427
04428
04429
if ((*fnGetData)(hDevice, pDataKey, pDataValue,
NULL, (
PBYTE)*ppDeviceData,
04430 *pdwSize, pdwSize) == ERROR_SUCCESS)
04431 {
04432 rc =
TRUE;
04433 }
04434
04435 EndGetDeviceData:
04436 (*fnCloseDevice)(hDevice);
04437
04438
return rc;
04439 }
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
BOOL
04465 SetDeviceData(
04466 LPCTSTR pDeviceName,
04467 DWORD dwClass,
04468 DWORD dwDataType,
04469 PVOID pDeviceData,
04470 DWORD dwSize
04471 )
04472 {
04473
BOOL rc =
FALSE;
04474
04475
if (dwClass == CLASS_MONITOR ||
04476 dwClass == CLASS_PRINTER ||
04477 dwClass == CLASS_SCANNER)
04478 {
04479 rc =
ISetDeviceData(pDeviceName, dwClass, dwDataType, pDeviceData, dwSize);
04480 }
04481
else if (dwClass == CLASS_COLORSPACE)
04482 {
04483 rc =
ISetDeviceData(pDeviceName, CLASS_MONITOR, dwDataType, pDeviceData, dwSize) ||
04484
ISetDeviceData(pDeviceName, CLASS_PRINTER, dwDataType, pDeviceData, dwSize) ||
04485
ISetDeviceData(pDeviceName, CLASS_SCANNER, dwDataType, pDeviceData, dwSize);
04486 }
04487
04488
return rc;
04489 }
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501
04502
04503
04504
04505
04506
04507
04508
04509
04510
BOOL
04511 ISetDeviceData(
04512 LPCTSTR pDeviceName,
04513 DWORD dwClass,
04514 DWORD dwDataType,
04515 PVOID pDeviceData,
04516 DWORD dwSize
04517 )
04518 {
04519 PRINTER_DEFAULTS
pd;
04520
PFNOPENDEVICE fnOpenDevice;
04521
PFNCLOSEDEVICE fnCloseDevice;
04522
PFNSETDEVICEDATA fnSetData;
04523 HANDLE hDevice;
04524 LPTSTR pDataKey;
04525 LPTSTR pDataValue;
04526
DWORD dwRegType = REG_BINARY;
04527
BOOL rc =
FALSE;
04528
04529
04530
04531
04532
04533
switch (dwClass)
04534 {
04535
case CLASS_PRINTER:
04536 fnOpenDevice = (
PFNOPENDEVICE)
OpenPrtr;
04537 fnCloseDevice = (
PFNCLOSEDEVICE)
ClosePrtr;
04538 fnSetData = (
PFNSETDEVICEDATA)
SetPrtrData;
04539
pd.pDatatype = __TEXT(
"RAW");
04540
pd.pDevMode =
NULL;
04541
pd.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
04542
break;
04543
04544
case CLASS_MONITOR:
04545 fnOpenDevice = (
PFNOPENDEVICE)
OpenMonitor;
04546 fnCloseDevice = (
PFNCLOSEDEVICE)
CloseMonitor;
04547 fnSetData = (
PFNSETDEVICEDATA)
SetMonitorData;
04548
break;
04549
04550
case CLASS_SCANNER:
04551 fnOpenDevice = (
PFNOPENDEVICE)
OpenScanner;
04552 fnCloseDevice = (
PFNCLOSEDEVICE)
CloseScanner;
04553 fnSetData = (
PFNSETDEVICEDATA)
SetScannerData;
04554
break;
04555
04556
default:
04557
return FALSE;
04558 }
04559
04560
04561
04562
04563
04564
switch (dwDataType)
04565 {
04566
case DEVICE_PROFILE_DATA:
04567
04568 pDataKey =
gszICMProfileListKey;
04569
04570
04571
04572
04573
04574
if (dwClass == CLASS_PRINTER)
04575 {
04576 pDataValue =
gszFiles;
04577 dwRegType = REG_MULTI_SZ;
04578 }
04579
else
04580 {
04581 pDataValue =
gszICMProfileListValue;
04582 }
04583
04584
break;
04585
04586
case DEVICE_PROFILE_ENUMMODE:
04587
04588 pDataKey =
gszICMDeviceDataKey;
04589 pDataValue =
gszICMProfileEnumMode;
04590
break;
04591
04592
default:
04593
return FALSE;
04594 }
04595
04596
04597
04598
04599
04600
if (! (*fnOpenDevice)((PTSTR)pDeviceName, &hDevice, (PTSTR)&
pd))
04601 {
04602
WARNING((__TEXT(
"Error opening device %s\n"), pDeviceName));
04603
return FALSE;
04604 }
04605
04606
04607
04608
04609
04610
if ((*fnSetData)(hDevice, pDataKey, pDataValue, dwRegType, (
PBYTE)pDeviceData,
04611 dwSize) == ERROR_SUCCESS)
04612 {
04613 rc =
TRUE;
04614 }
04615
04616
#if !defined(_WIN95_)
04617
04618
04619
04620
04621
04622
if ((rc ==
TRUE) && (dwClass == CLASS_PRINTER) && (dwDataType ==
DEVICE_PROFILE_DATA))
04623 {
04624
if (((*fnSetData)(hDevice, pDataKey,
gszDirectory, REG_SZ, (
PBYTE)
gszColorDir,
04625 (lstrlen(
gszColorDir) + 1)*
sizeof(TCHAR)) != ERROR_SUCCESS) ||
04626 ((*fnSetData)(hDevice, pDataKey,
gszModule, REG_SZ, (
PBYTE)
gszMSCMS,
04627 (lstrlen(
gszMSCMS) + 1)*
sizeof(TCHAR)) != ERROR_SUCCESS))
04628 {
04629 rc =
FALSE;
04630 }
04631 }
04632
04633
#endif
04634
04635 (*fnCloseDevice)(hDevice);
04636
04637
return rc;
04638 }
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
BOOL
04659 IsStringInMultiSz(
04660 PTSTR pMultiSzString,
04661 PTSTR pString
04662 )
04663 {
04664
BOOL rc =
FALSE;
04665
04666
while (*pMultiSzString)
04667 {
04668
if (! lstrcmpi(pMultiSzString, pString))
04669 {
04670 rc =
TRUE;
04671
break;
04672 }
04673
04674 pMultiSzString += lstrlen(pMultiSzString) + 1;
04675 }
04676
04677
return rc;
04678 }
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
DWORD
04699 RemoveStringFromMultiSz(
04700 PTSTR pMultiSzString,
04701 PTSTR pString,
04702 DWORD dwSize
04703 )
04704 {
04705
DWORD dwCount = dwSize;
04706
04707
while (*pMultiSzString)
04708 {
04709 dwCount -= (lstrlen(pMultiSzString) + 1) *
sizeof(TCHAR);
04710
04711
if (! lstrcmpi(pMultiSzString, pString))
04712 {
04713
break;
04714 }
04715
04716 pMultiSzString += lstrlen(pMultiSzString) + 1;
04717 }
04718
04719
MyCopyMemory((
PBYTE)pMultiSzString, (
PBYTE)(pMultiSzString + lstrlen(pString) + 1), dwCount);
04720
04721
return dwSize -
sizeof(TCHAR) * (lstrlen(pString) + 1);
04722 }
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743
04744 #define SET(pEnumRecord, bit) ((pEnumRecord)->dwFields & (bit))
04745
04746
MATCHTYPE
04747 DoesProfileMatchEnumRecord(
04748 PTSTR pProfileName,
04749 PENUMTYPE pEnumRecord
04750 )
04751 {
04752 PROFILEHEADER header;
04753 PROFILE prof;
04754 HPROFILE hProfile =
NULL;
04755
MATCHTYPE rc =
NOMATCH;
04756
04757
04758
04759
04760
04761 prof.dwType = PROFILE_FILENAME;
04762 prof.pProfileData = (PVOID)pProfileName;
04763 prof.cbDataSize = (lstrlen(pProfileName) + 1) *
sizeof(TCHAR);
04764
04765 hProfile = OpenColorProfile(&prof, PROFILE_READ, FILE_SHARE_READ,
04766
OPEN_EXISTING);
04767
if (! hProfile)
04768 {
04769
WARNING((__TEXT(
"Error opening profile %s\n"), pProfileName));
04770
goto EndDoesProfileMatchEnumRecord;
04771 }
04772
04773
04774
04775
04776
04777
if (!
GetColorProfileHeader(hProfile, &header))
04778 {
04779
ERR((__TEXT(
"Error getting color profile header for %s\n"), pProfileName));
04780
goto EndDoesProfileMatchEnumRecord;
04781 }
04782
04783
if ((!
SET(pEnumRecord, ET_CMMTYPE) || (pEnumRecord->dwCMMType == header.phCMMType)) &&
04784 (!
SET(pEnumRecord, ET_CLASS) || (pEnumRecord->dwClass == header.phClass)) &&
04785 (!
SET(pEnumRecord, ET_DATACOLORSPACE) || (pEnumRecord->dwDataColorSpace == header.phDataColorSpace)) &&
04786 (!
SET(pEnumRecord, ET_CONNECTIONSPACE) || (pEnumRecord->dwConnectionSpace == header.phConnectionSpace)) &&
04787 (!
SET(pEnumRecord, ET_SIGNATURE) || (pEnumRecord->dwSignature == header.phSignature)) &&
04788 (!
SET(pEnumRecord, ET_PLATFORM) || (pEnumRecord->dwPlatform == header.phPlatform)) &&
04789 (!
SET(pEnumRecord, ET_PROFILEFLAGS) || (pEnumRecord->dwProfileFlags == header.phProfileFlags)) &&
04790 (!
SET(pEnumRecord, ET_MANUFACTURER) || (pEnumRecord->dwManufacturer == header.phManufacturer)) &&
04791 (!
SET(pEnumRecord, ET_MODEL) || (pEnumRecord->dwModel == header.phModel)) &&
04792 (!
SET(pEnumRecord, ET_ATTRIBUTES) || (pEnumRecord->dwAttributes[0] == header.phAttributes[0] &&
04793 pEnumRecord->dwAttributes[1] == header.phAttributes[1])) &&
04794 (!
SET(pEnumRecord, ET_RENDERINGINTENT) || (pEnumRecord->dwRenderingIntent == header.phRenderingIntent)) &&
04795 (!
SET(pEnumRecord, ET_CREATOR) || (pEnumRecord->dwCreator == header.phCreator)))
04796 {
04797 rc =
EXACT_MATCH;
04798 }
04799
04800
04801
04802
04803
04804
if (rc !=
NOMATCH &&
SET(pEnumRecord, ET_RESOLUTION|ET_MEDIATYPE|ET_DITHERMODE))
04805 {
04806 rc =
CheckResMedHftnMatch(hProfile, pEnumRecord);
04807 }
04808
04809 EndDoesProfileMatchEnumRecord:
04810
if (hProfile)
04811 {
04812
CloseColorProfile(hProfile);
04813 }
04814
04815
return rc;
04816 }
04817
04818
04819
04820
04821
04822
04823
04824
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
MATCHTYPE
04841 CheckResMedHftnMatch(
04842 HPROFILE hProfile,
04843 PENUMTYPE pEnumRecord
04844 )
04845 {
04846 PDEVICESETTINGS pDevSettings =
NULL;
04847 PPLATFORMENTRY pPlatform;
04848 PSETTINGCOMBOS pCombo;
04849 PSETTINGS pSetting;
04850
DWORD dwMSData[4];
04851
DWORD dwSize, i, iMax, j, jMax;
04852
MATCHTYPE rc =
MATCH;
04853
BOOL bReference;
04854
04855
04856
04857
04858
04859 dwSize = 0;
04860
GetColorProfileElement(hProfile,
TAG_DEVICESETTINGS, 0, &dwSize,
NULL, &bReference);
04861
04862
if (dwSize > 0)
04863 {
04864
if (!(pDevSettings = (PDEVICESETTINGS)GlobalAllocPtr(GHND, dwSize)))
04865 {
04866
WARNING((__TEXT(
"Error allocating memory\n")));
04867
return NOMATCH;
04868 }
04869
04870
if (
GetColorProfileElement(hProfile,
TAG_DEVICESETTINGS, 0, &dwSize, (
PBYTE)pDevSettings, &bReference))
04871 {
04872 pPlatform = &pDevSettings->PlatformEntry[0];
04873
04874
04875
04876
04877
04878 i = 0;
04879 iMax = FIX_ENDIAN(pDevSettings->nPlatforms);
04880
while ((i < iMax) && (pPlatform->PlatformID !=
ID_MSFT_REVERSED))
04881
04882 {
04883 i++;
04884 pPlatform = (PPLATFORMENTRY)((
PBYTE)pPlatform + FIX_ENDIAN(pPlatform->dwSize));
04885 }
04886
04887
if (i >= iMax)
04888 {
04889
04890
04891
04892
04893
04894
goto EndCheckResMedHftnMatch;
04895 }
04896
04897
04898
04899
04900
04901 pCombo = &pPlatform->SettingCombos[0];
04902 iMax = FIX_ENDIAN(pPlatform->nSettingCombos);
04903
for (i=0; i<iMax; i++)
04904 {
04905
04906
04907
04908
04909 pSetting = &pCombo->Settings[0];
04910 jMax = FIX_ENDIAN(pCombo->nSettings);
04911
for (j=0; j<jMax; j++)
04912 {
04913
if (pSetting->dwSettingType ==
ID_MEDIATYPE_REVERSED)
04914 {
04915
if (
SET(pEnumRecord, ET_MEDIATYPE) &&
04916 !
DwordMatches(pSetting, pEnumRecord->dwMediaType))
04917 {
04918
goto NextCombo;
04919 }
04920 }
04921
else if (pSetting->dwSettingType ==
ID_DITHER_REVERSED)
04922 {
04923
if (
SET(pEnumRecord, ET_DITHERMODE) &&
04924 !
DwordMatches(pSetting, pEnumRecord->dwDitheringMode))
04925 {
04926
goto NextCombo;
04927 }
04928 }
04929
else if (pSetting->dwSettingType ==
ID_RESLN_REVERSED)
04930 {
04931
if (
SET(pEnumRecord, ET_RESOLUTION) &&
04932 !
QwordMatches(pSetting, &pEnumRecord->dwResolution[0]))
04933 {
04934
goto NextCombo;
04935 }
04936 }
04937
04938 pSetting = (PSETTINGS)((
PBYTE)pSetting +
sizeof(SETTINGS) -
sizeof(
DWORD) +
04939 FIX_ENDIAN(pSetting->dwSizePerValue) * FIX_ENDIAN(pSetting->nValues));
04940 }
04941
04942
04943
04944
04945
04946 rc =
EXACT_MATCH;
04947
goto EndCheckResMedHftnMatch;
04948
04949 NextCombo:
04950 pCombo = (PSETTINGCOMBOS)((
PBYTE)pCombo + FIX_ENDIAN(pCombo->dwSize));
04951 }
04952
04953 rc =
NOMATCH;
04954
goto EndCheckResMedHftnMatch;
04955
04956 }
04957
else
04958 {
04959 rc =
NOMATCH;
04960
goto EndCheckResMedHftnMatch;
04961 }
04962 }
04963
else
04964 {
04965
04966
04967
04968
04969 dwSize =
sizeof(dwMSData);
04970
if (
SET(pEnumRecord, ET_MEDIATYPE))
04971 {
04972
if (
GetColorProfileElement(hProfile,
TAG_MS01, 0, &dwSize, dwMSData, &bReference))
04973 {
04974 rc =
EXACT_MATCH;
04975
04976
if (pEnumRecord->dwMediaType != FIX_ENDIAN(dwMSData[2]))
04977 {
04978
return NOMATCH;
04979 }
04980 }
04981 }
04982
04983 dwSize =
sizeof(dwMSData);
04984
if (
SET(pEnumRecord, ET_DITHERMODE))
04985 {
04986
if (
GetColorProfileElement(hProfile,
TAG_MS02, 0, &dwSize, dwMSData, &bReference))
04987 {
04988 rc =
EXACT_MATCH;
04989
04990
if (pEnumRecord->dwDitheringMode != FIX_ENDIAN(dwMSData[2]))
04991 {
04992
return NOMATCH;
04993 }
04994 }
04995 }
04996
04997 dwSize =
sizeof(dwMSData);
04998
if (
SET(pEnumRecord, ET_RESOLUTION))
04999 {
05000
if (
GetColorProfileElement(hProfile,
TAG_MS03, 0, &dwSize, dwMSData, &bReference))
05001 {
05002 rc =
EXACT_MATCH;
05003
05004
if (pEnumRecord->dwResolution[0] != FIX_ENDIAN(dwMSData[2]) ||
05005 pEnumRecord->dwResolution[1] != FIX_ENDIAN(dwMSData[3]))
05006 {
05007
return NOMATCH;
05008 }
05009 }
05010 }
05011 }
05012
05013 EndCheckResMedHftnMatch:
05014
05015
if (pDevSettings)
05016 {
05017 GlobalFreePtr(pDevSettings);
05018 }
05019
05020
return rc;
05021 }
05022
05023
05024
BOOL
05025 DwordMatches(
05026 PSETTINGS pSetting,
05027 DWORD dwValue
05028 )
05029 {
05030
DWORD i, iMax;
05031 PDWORD pValue;
05032
05033 dwValue = FIX_ENDIAN(dwValue);
05034
05035
05036
05037
05038
05039 pValue = &pSetting->Value[0];
05040 iMax = FIX_ENDIAN(pSetting->nValues);
05041
for (i=0; i<iMax; i++)
05042 {
05043
if (dwValue == *pValue)
05044 {
05045
return TRUE;
05046 }
05047
05048 pValue++;
05049 }
05050
05051
return FALSE;
05052 }
05053
05054
05055
BOOL
05056 QwordMatches(
05057 PSETTINGS pSetting,
05058 PDWORD pdwValue
05059 )
05060 {
05061
DWORD i, iMax, dwValue1, dwValue2;
05062 PDWORD pValue;
05063
05064 dwValue1 = FIX_ENDIAN(*pdwValue);
05065 dwValue2 = FIX_ENDIAN(*(pdwValue+1));
05066
05067
05068
05069
05070
05071 pValue = &pSetting->Value[0];
05072 iMax = FIX_ENDIAN(pSetting->nValues);
05073
for (i=0; i<iMax; i++)
05074 {
05075
if ((dwValue1 == *pValue) && (dwValue2 == *(pValue + 1)))
05076 {
05077
return TRUE;
05078 }
05079
05080 pValue += 2;
05081 }
05082
05083
return FALSE;
05084 }
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104
05105
05106
BOOL WINAPI
05107 OpenPrtr(
05108 PTSTR pDeviceName,
05109 LPHANDLE phDevice,
05110 PTSTR pDummy
05111 )
05112 {
05113
#if !defined(_WIN95_)
05114
return OpenPrinter(pDeviceName, phDevice, (LPPRINTER_DEFAULTS)pDummy);
05115
#else
05116
HKEY hkDevice =
NULL;
05117 HKEY hkPrtr =
NULL;
05118
DWORD dwErr;
05119
BOOL rc =
FALSE;
05120
05121 *phDevice =
NULL;
05122
05123
if (((dwErr = RegOpenKey(HKEY_LOCAL_MACHINE, gszRegPrinter, &hkDevice)) != ERROR_SUCCESS) ||
05124 ((dwErr = RegOpenKey(hkDevice, pDeviceName, &hkPrtr)) != ERROR_SUCCESS) ||
05125 ((dwErr = RegOpenKey(hkPrtr, gszPrinterData, (HKEY *)phDevice)) != ERROR_SUCCESS))
05126 {
05127
WARNING((__TEXT(
"Cannot open printer data branch of registry for %s: %d\n"), pDeviceName, dwErr));
05128 SetLastError(dwErr);
05129
goto EndOpenPrtr;
05130 }
05131
05132 rc =
TRUE;
05133
05134 EndOpenPrtr:
05135
if (hkDevice)
05136 {
05137 RegCloseKey(hkDevice);
05138 }
05139
if (hkPrtr)
05140 {
05141 RegCloseKey(hkPrtr);
05142 }
05143
05144
return rc;
05145
#endif
05146
}
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
BOOL WINAPI
05166 ClosePrtr(
05167 HANDLE hDevice
05168 )
05169 {
05170
#if !defined(_WIN95_)
05171
return ClosePrinter(hDevice);
05172
#else
05173
DWORD dwErr;
05174
05175 dwErr = RegCloseKey((HKEY)hDevice);
05176 SetLastError(dwErr);
05177
return dwErr == ERROR_SUCCESS;
05178
#endif
05179
}
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
DWORD WINAPI
05204 GetPrtrData(
05205 HANDLE hDevice,
05206 PTSTR pKey,
05207 PTSTR pName,
05208 PDWORD pdwType,
05209 PBYTE pData,
05210 DWORD dwSize,
05211 PDWORD pdwNeeded
05212 )
05213 {
05214
#if !defined(_WIN95_)
05215
return GetPrinterDataEx(hDevice, pKey, pName, pdwType, pData, dwSize, pdwNeeded);
05216
#else
05217
*pdwNeeded = dwSize;
05218
05219
return RegQueryValueEx((HKEY)hDevice, pName, 0,
NULL, pData, pdwNeeded);
05220
#endif
05221
}
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244
DWORD WINAPI
05245 SetPrtrData(
05246 HANDLE hDevice,
05247 PTSTR pKey,
05248 PTSTR pName,
05249 DWORD dwType,
05250 PBYTE pData,
05251 DWORD dwSize
05252 )
05253 {
05254
#if !defined(_WIN95_)
05255
return SetPrinterDataEx(hDevice, pKey, pName, dwType, pData, dwSize);
05256
#else
05257
return RegSetValueEx((HKEY)hDevice, pName, 0, dwType, pData, dwSize);
05258
#endif
05259
}
05260
05261
05262
05263
05264
05265
05266
05267
05268
05269
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279
BOOL WINAPI
05280 OpenMonitor(
05281 PTSTR pDeviceName,
05282 LPHANDLE phDevice,
05283 PTSTR pDummy
05284 )
05285 {
05286
#ifdef _WIN95_
05287
05288
05289
05290
05291
05292 HDEVINFO hDevInfo =
INVALID_HANDLE_VALUE;
05293 HKEY hkICM =
NULL;
05294 HKEY hkDriver =
NULL;
05295
DWORD dwSize;
05296 TCHAR
szName[
MAX_PATH];
05297
BOOL rc =
FALSE;
05298 SP_DEVINFO_DATA spdid;
05299
int i;
05300
05301
if (!LoadSetupAPIDll())
05302 {
05303
WARNING((__TEXT(
"Error loading setupapi.dll: %d\n"), GetLastError()));
05304
return FALSE;
05305 }
05306
05307 hDevInfo = (*fpSetupDiGetClassDevs)((LPGUID)&GUID_DEVCLASS_MONITOR,
NULL,
NULL, DIGCF_PRESENT);
05308
05309
if (hDevInfo ==
INVALID_HANDLE_VALUE)
05310 {
05311
WARNING((__TEXT(
"Error getting hDevInfo: %d\n"), GetLastError()));
05312
goto EndOpenMonitor;
05313 }
05314
05315 i = 0;
05316
while (! rc)
05317 {
05318 ZeroMemory(&spdid,
sizeof(SP_DEVINFO_DATA));
05319 spdid.cbSize =
sizeof(SP_DEVINFO_DATA);
05320
if (! (*fpSetupDiEnumDeviceInfo)(hDevInfo, i, &spdid))
05321 {
05322
if (i == 0 && !lstrcmpi(pDeviceName,
gszDisplay))
05323 {
05324
05325
05326
05327
05328 TCHAR szICMMonitorData[] = __TEXT(
"ICMMonitorData");
05329
05330
WARNING((__TEXT(
"PnP support absent - Using DISPLAY\n")));
05331
05332
05333
05334
05335
05336
if ((RegOpenKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM) != ERROR_SUCCESS) ||
05337 (RegCreateKey(hkICM, szICMMonitorData, &hkDriver) != ERROR_SUCCESS))
05338 {
05339
WARNING((__TEXT(
"Cannot open ICMMonitorData branch of registry\n")));
05340
goto EndOpenMonitor;
05341 }
05342 rc =
TRUE;
05343 }
05344
break;
05345 }
05346
05347
05348
05349
05350
05351 dwSize =
sizeof(
szName);
05352
if ((*fpSetupDiGetDeviceInstanceId)(hDevInfo, &spdid,
szName, dwSize,
NULL) &&
05353 ! lstrcmp(
szName, pDeviceName))
05354 {
05355 hkDriver = (*fpSetupDiOpenDevRegKey)(hDevInfo, &spdid, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
05356
if (hkDriver ==
INVALID_HANDLE_VALUE)
05357 {
05358
WARNING((__TEXT(
"Could not open monitor s/w key for all access\n")));
05359 hkDriver = (*fpSetupDiOpenDevRegKey)(hDevInfo, &spdid, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
05360
if (hkDriver ==
INVALID_HANDLE_VALUE)
05361 {
05362
WARNING((__TEXT(
"Error opening s/w registry key for read access: %x\n"), GetLastError()));
05363
goto EndOpenMonitor;
05364 }
05365 }
05366
05367 rc =
TRUE;
05368 }
05369
05370 i++;
05371 }
05372
05373 EndOpenMonitor:
05374
05375
if (hkICM)
05376 {
05377 RegCloseKey(hkICM);
05378 }
05379
05380
if (hDevInfo !=
INVALID_HANDLE_VALUE)
05381 {
05382 (*fpSetupDiDestroyDeviceInfoList)(hDevInfo);
05383 }
05384
05385 *phDevice = (HANDLE)hkDriver;
05386
05387
return rc;
05388
05389
#else
05390
05391
05392
05393
05394
05395 TCHAR szRegPath[
MAX_PATH];
05396 HKEY hkDriver =
NULL;
05397
05398
05399
05400
05401
05402 lstrcpy(szRegPath,
gszDeviceClass);
05403 lstrcat(szRegPath,
gszMonitorGUID);
05404
05405
if (!lstrcmpi(pDeviceName,
gszDisplay))
05406 {
05407
WARNING((__TEXT(
"PnP support absent - Using DISPLAY\n")));
05408
05409
05410
05411
05412
05413 lstrcat(szRegPath,TEXT(
"\\0000"));
05414 }
05415
else if (_tcsstr(pDeviceName,
gszMonitorGUID))
05416 {
05417
05418
05419
05420
05421 TCHAR *pDeviceNumber = _tcsrchr(pDeviceName,TEXT(
'\\'));
05422
05423
if (pDeviceNumber)
05424 {
05425 lstrcat(szRegPath,pDeviceNumber);
05426 }
05427
else
05428 {
05429 lstrcat(szRegPath,TEXT(
"\\0000"));
05430 }
05431 }
05432
else
05433 {
05434
05435
05436
05437
goto EndOpenMonitor;
05438 }
05439
05440
05441
05442
05443
05444
if (RegOpenKey(HKEY_LOCAL_MACHINE, szRegPath, &hkDriver) != ERROR_SUCCESS)
05445 {
05446
WARNING((__TEXT(
"Cannot open %s key\n"),szRegPath));
05447 hkDriver =
NULL;
05448 }
05449
05450 EndOpenMonitor:
05451
05452 *phDevice = (HANDLE) hkDriver;
05453
05454
return (hkDriver !=
NULL);
05455
05456
#endif // _WIN95_
05457
}
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
BOOL WINAPI
05476 CloseMonitor(
05477 HANDLE hDevice
05478 )
05479 {
05480
DWORD dwErr;
05481
05482 dwErr = RegCloseKey((HKEY)hDevice);
05483 SetLastError(dwErr);
05484
return (dwErr == ERROR_SUCCESS);
05485 }
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
DWORD WINAPI
05510 GetMonitorData(
05511 HANDLE hDevice,
05512 PTSTR pKey,
05513 PTSTR pName,
05514 PDWORD pdwType,
05515 PBYTE pData,
05516 DWORD dwSize,
05517 PDWORD pdwNeeded
05518 )
05519 {
05520
DWORD dwType, dwTemp;
05521
DWORD rc;
05522
05523 *pdwNeeded = dwSize;
05524
05525 rc = RegQueryValueEx((HKEY)hDevice, pName, 0, &dwType, pData, pdwNeeded);
05526
if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
05527 {
05528
if (dwType == REG_SZ)
05529 {
05530 PTSTR pFilename;
05531
05532
05533
05534
05535
05536
if (pData)
05537 {
05538 pFilename =
GetFilenameFromPath((PTSTR)pData);
05539
if (pFilename != (PTSTR)pData)
05540 {
05541 lstrcpy((PTSTR)pData, pFilename);
05542 }
05543 *pdwNeeded = lstrlen((PTSTR)pData) *
sizeof(TCHAR);
05544 }
05545
05546 *pdwNeeded +=
sizeof(TCHAR);
05547
05548
if ((dwSize >= *pdwNeeded) && pData)
05549 {
05550 *((PTSTR)pData + lstrlen((PTSTR)pData) + 1) =
'\0';
05551
05552
05553
05554
05555
05556 RegSetValueEx((HKEY)hDevice, pName, 0, REG_BINARY, pData, (lstrlen((PTSTR)pData)+2)*
sizeof(TCHAR));
05557 }
05558 }
05559
else if (*pdwNeeded == 1)
05560 {
05561
05562
05563
05564
05565
05566
05567
05568
05569
05570
if (!pData || *pData != 0)
05571 {
05572
05573
05574
05575
05576
if ((dwSize >=
MAX_PATH) && pData)
05577 {
05578 HKEY hkICM =
NULL;
05579 HKEY hkDevice =
NULL;
05580
REGDATA regData;
05581
05582
05583
05584
05585
05586
if (pData[0] >
sizeof(
gszDispProfiles)/
sizeof(
gszDispProfiles[0]))
05587 {
05588
WARNING((__TEXT(
"Predefined profile index too large: %d\n"), pData[0]));
05589
goto EndCompatMode;
05590 }
05591
05592 lstrcpy((PTSTR)pData,
gszDispProfiles[pData[0] - 1]);
05593 *((PTSTR)pData + lstrlen((PTSTR)pData) + 1) =
'\0';
05594
05595
05596
05597
05598
05599
05600
05601
05602
if ((RegCreateKey(HKEY_LOCAL_MACHINE,
gszICMRegPath, &hkICM) != ERROR_SUCCESS) ||
05603 (RegCreateKey(hkICM, __TEXT(
"mntr"), &hkDevice) != ERROR_SUCCESS))
05604 {
05605
WARNING((__TEXT(
"Cannot open ICM\\device branch of registry\n")));
05606
goto EndCompatMode;
05607 }
05608
05609
05610
05611
05612
05613
05614 dwTemp =
sizeof(
REGDATA);
05615
if (RegQueryValueEx(hkDevice, (PTSTR)pData, 0,
NULL, (
PBYTE)®Data,
05616 &dwTemp) == ERROR_SUCCESS)
05617 {
05618 regData.dwRefCount++;
05619 }
05620
else
05621 {
05622 regData.dwRefCount = 1;
05623 regData.dwManuID = 'enon';
05624 regData.dwModelID = 'enon';
05625 }
05626
05627
if (RegSetValueEx(hkDevice, (PTSTR)pData, 0, REG_BINARY,
05628 (
PBYTE)®Data,
sizeof(
REGDATA)) != ERROR_SUCCESS)
05629 {
05630
WARNING((__TEXT(
"Error setting registry value\n")));
05631
goto EndCompatMode;
05632 }
05633
05634
05635
05636
05637
05638 RegSetValueEx((HKEY)hDevice, pName, 0, REG_BINARY, pData,
05639 (lstrlen((PTSTR)pData) + 2)*
sizeof(TCHAR));
05640
05641 EndCompatMode:
05642
if (hkICM)
05643 {
05644 RegCloseKey(hkICM);
05645 }
05646
if (hkDevice)
05647 {
05648 RegCloseKey(hkDevice);
05649 }
05650 }
05651 *pdwNeeded =
MAX_PATH;
05652 }
05653 }
05654 }
05655
05656
if ((rc == ERROR_SUCCESS) && (*pdwNeeded > dwSize))
05657 {
05658 rc = ERROR_MORE_DATA;
05659 }
05660
05661
return rc;
05662 }
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683
05684
05685
DWORD WINAPI
05686 SetMonitorData(
05687 HANDLE hDevice,
05688 PTSTR pKey,
05689 PTSTR pName,
05690 DWORD dwType,
05691 PBYTE pData,
05692 DWORD dwSize
05693 )
05694 {
05695
return RegSetValueEx((HKEY)hDevice, pName, 0, dwType, pData, dwSize);
05696 }
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
BOOL WINAPI
05717 OpenScanner(
05718 PTSTR pDeviceName,
05719 LPHANDLE phDevice,
05720 PTSTR pDummy
05721 )
05722 {
05723
PFNSTICREATEINSTANCE pStiCreateInstance;
05724
PSCANNERDATA psd =
NULL;
05725 HRESULT hres;
05726
BOOL bRc =
FALSE;
05727
05728
if (!(psd = (
PSCANNERDATA)
MemAlloc(
sizeof(
SCANNERDATA))))
05729 {
05730
WARNING((__TEXT(
"Error allocating memory for scanner data\n")));
05731
return FALSE;
05732 }
05733
05734
if (!(psd->
pDeviceName =
MemAlloc((lstrlen(pDeviceName) + 1) *
sizeof(WCHAR))))
05735 {
05736
WARNING((__TEXT(
"Error allocating memory for scanner name\n")));
05737
goto EndOpenScanner;
05738 }
05739
05740
#ifdef UNICODE
05741
lstrcpy(psd->
pDeviceName, pDeviceName);
05742
#else
05743
if (!
ConvertToUnicode(pDeviceName, &psd->
pDeviceName,
FALSE))
05744 {
05745
WARNING((__TEXT(
"Error converting scanner name to Unicode\n")));
05746
goto EndOpenScanner;
05747 }
05748
#endif
05749
05750
if (!(psd->
hModule = LoadLibrary(
gszStiDll)))
05751 {
05752
WARNING((__TEXT(
"Error loading sti.dll: %d\n"), GetLastError()));
05753
goto EndOpenScanner;
05754 }
05755
05756
if (!(pStiCreateInstance = (
PFNSTICREATEINSTANCE)GetProcAddress(psd->
hModule,
gszStiCreateInstance)))
05757 {
05758
WARNING((__TEXT(
"Error getting proc StiCreateInstance\n")));
05759
goto EndOpenScanner;
05760 }
05761
05762 hres = (*pStiCreateInstance)(GetModuleHandle(
NULL),
STI_VERSION, &psd->
pSti,
NULL);
05763
05764
if (FAILED(hres))
05765 {
05766
WARNING((__TEXT(
"Error creating sti instance: %d\n"), hres));
05767
goto EndOpenScanner;
05768 }
05769
05770 *phDevice = (HANDLE)psd;
05771
05772 bRc =
TRUE;
05773
05774 EndOpenScanner:
05775
05776
if (!bRc && psd)
05777 {
05778
CloseScanner((HANDLE)psd);
05779 }
05780
05781
return bRc;
05782 }
05783
05784
05785
05786
05787
05788
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798
05799
05800
BOOL WINAPI
05801 CloseScanner(
05802 HANDLE hDevice
05803 )
05804 {
05805
PSCANNERDATA psd = (
PSCANNERDATA)hDevice;
05806
05807
if (psd)
05808 {
05809
if (psd->
pSti)
05810 {
05811 psd->
pSti->lpVtbl->Release(psd->
pSti);
05812 }
05813
05814
if (psd->
pDeviceName)
05815 {
05816
MemFree(psd->
pDeviceName);
05817 }
05818
05819
if (psd->
hModule)
05820 {
05821 FreeLibrary(psd->
hModule);
05822 }
05823
05824
MemFree(psd);
05825 }
05826
05827
return TRUE;
05828 }
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839
05840
05841
05842
05843
05844
05845
05846
05847
05848
05849
05850
05851
05852
DWORD WINAPI
05853 GetScannerData(
05854 HANDLE hDevice,
05855 PTSTR pKey,
05856 PTSTR pName,
05857 PDWORD pdwType,
05858 PBYTE pData,
05859 DWORD dwSize,
05860 PDWORD pdwNeeded
05861 )
05862 {
05863
PSCANNERDATA psd = (
PSCANNERDATA)hDevice;
05864 HRESULT hres;
05865
#ifndef UNICODE
05866
PWSTR pwszName;
05867
05868
05869
05870
05871 hres =
ConvertToUnicode(pName, &pwszName,
TRUE);
05872
05873
if (!hres)
05874 {
05875
return (ERROR_INVALID_PARAMETER);
05876 }
05877
05878 pName = (PSTR)pwszName;
05879
05880
#endif
05881
05882 *pdwNeeded = dwSize;
05883
05884 hres = psd->
pSti->lpVtbl->GetDeviceValue(psd->
pSti, psd->
pDeviceName, (PWSTR)pName, pdwType, pData, pdwNeeded);
05885
05886
#ifndef UNICODE
05887
05888
MemFree(pwszName);
05889
05890
#endif
05891
05892
return hres;
05893 }
05894
05895
05896
05897
05898
05899
05900
05901
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
DWORD WINAPI
05917 SetScannerData(
05918 HANDLE hDevice,
05919 PTSTR pKey,
05920 PTSTR pName,
05921 DWORD dwType,
05922 PBYTE pData,
05923 DWORD dwSize
05924 )
05925 {
05926
PSCANNERDATA psd = (
PSCANNERDATA)hDevice;
05927 HRESULT hres;
05928
#ifndef UNICODE
05929
PWSTR pwszName;
05930
05931
05932
05933
05934 hres =
ConvertToUnicode(pName, &pwszName,
TRUE);
05935
05936
if (!hres)
05937 {
05938
return (ERROR_INVALID_PARAMETER);
05939 }
05940
05941 pName = (PSTR)pwszName;
05942
05943
#endif
05944
05945 hres = psd->
pSti->lpVtbl->SetDeviceValue(psd->
pSti, psd->
pDeviceName, (PWSTR)pName, dwType, pData, dwSize);
05946
05947
#ifndef UNICODE
05948
05949
MemFree(pwszName);
05950
05951
#endif
05952
05953
return hres;
05954 }
05955
05956
05957
05958
05959
05960
BOOL WINAPI
05961 InternalGetDeviceConfig(
05962 LPCTSTR pDeviceName,
05963 DWORD dwDeviceClass,
05964 DWORD dwConfigType,
05965 PVOID pConfigData,
05966 PDWORD pdwSize
05967 )
05968 {
05969
DWORD dwDataType;
05970
DWORD dwSizeRequired = 0;
05971
BOOL rc =
FALSE;
05972
05973
switch (dwConfigType)
05974 {
05975
case MSCMS_PROFILE_ENUM_MODE:
05976
05977 dwDataType =
DEVICE_PROFILE_ENUMMODE;
05978
break;
05979
05980
default:
05981
05982
WARNING((__TEXT(
"Invalid parameter to InternalGetDeviceConfig\n")));
05983 SetLastError(ERROR_INVALID_PARAMETER);
05984
return FALSE;
05985 }
05986
05987
05988
05989
05990
05991
if (
GetDeviceData(pDeviceName,dwDeviceClass,dwDataType,
NULL,&dwSizeRequired,
FALSE))
05992 {
05993
if ((dwSizeRequired <= *pdwSize) && (pConfigData !=
NULL))
05994 {
05995
05996
05997
05998
05999
if (
GetDeviceData(pDeviceName,dwDeviceClass,dwDataType,
06000 (PVOID *)&pConfigData,pdwSize,
FALSE))
06001 {
06002 rc =
TRUE;
06003 }
06004
else
06005 {
06006
WARNING((__TEXT(
"Failed on GetDeviceData to query data\n")));
06007 SetLastError(ERROR_INVALID_PARAMETER);
06008 }
06009 }
06010
else
06011 {
06012
06013
06014
06015
06016 *pdwSize = dwSizeRequired;
06017 SetLastError(ERROR_INSUFFICIENT_BUFFER);
06018 }
06019 }
06020
else
06021 {
06022
WARNING((__TEXT(
"Failed on GetDeviceData to query data size\n")));
06023 SetLastError(ERROR_INVALID_PARAMETER);
06024 }
06025
06026
return rc;
06027 }
06028
06029
BOOL WINAPI
06030 InternalSetDeviceConfig(
06031 LPCTSTR pDeviceName,
06032 DWORD dwDeviceClass,
06033 DWORD dwConfigType,
06034 PVOID pConfigData,
06035 DWORD dwSize
06036 )
06037 {
06038
DWORD dwDataType;
06039
06040
switch (dwConfigType)
06041 {
06042
case MSCMS_PROFILE_ENUM_MODE:
06043
06044 dwDataType =
DEVICE_PROFILE_ENUMMODE;
06045
break;
06046
06047
default:
06048
06049
WARNING((__TEXT(
"Invalid parameter to InternalGetDeviceConfig\n")));
06050 SetLastError(ERROR_INVALID_PARAMETER);
06051
return FALSE;
06052 }
06053
06054
06055
06056
06057
06058
return (
SetDeviceData(pDeviceName,dwDeviceClass,dwDataType,pConfigData,dwSize));
06059 }
06060
06061
#ifdef _WIN95_
06062
06063
06064
06065
06066
06067
BOOL
06068 LoadSetupAPIDll(
06069 VOID
06070 )
06071 {
06072 EnterCriticalSection(&critsec);
06073
06074
if (
ghModSetupAPIDll ==
NULL)
06075 {
06076
ghModSetupAPIDll = LoadLibrary(TEXT(
"setupapi.dll"));
06077
06078
if (
ghModSetupAPIDll)
06079 {
06080
fpSetupDiOpenDevRegKey = (
FP_SetupDiOpenDevRegKey)
06081 GetProcAddress(ghModSetupAPIDll,
"SetupDiOpenDevRegKey");
06082
fpSetupDiDestroyDeviceInfoList = (
FP_SetupDiDestroyDeviceInfoList)
06083 GetProcAddress(ghModSetupAPIDll,
"SetupDiDestroyDeviceInfoList");
06084
fpSetupDiEnumDeviceInfo = (
FP_SetupDiEnumDeviceInfo)
06085 GetProcAddress(ghModSetupAPIDll,
"SetupDiEnumDeviceInfo");
06086
fpSetupDiGetDeviceInstanceId = (
FP_SetupDiGetDeviceInstanceId)
06087 GetProcAddress(ghModSetupAPIDll,
"SetupDiGetDeviceInstanceIdA");
06088
fpSetupDiGetClassDevs = (
FP_SetupDiGetClassDevs)
06089 GetProcAddress(ghModSetupAPIDll,
"SetupDiGetClassDevsA");
06090
06091
if ((
fpSetupDiOpenDevRegKey ==
NULL) ||
06092 (
fpSetupDiDestroyDeviceInfoList ==
NULL) ||
06093 (
fpSetupDiEnumDeviceInfo ==
NULL) ||
06094 (
fpSetupDiGetDeviceInstanceId ==
NULL) ||
06095 (
fpSetupDiGetClassDevs ==
NULL))
06096 {
06097
WARNING((__TEXT(
"Could not find Export function in setupapi.dll\n")));
06098
06099 FreeLibrary(ghModSetupAPIDll);
06100
ghModSetupAPIDll =
NULL;
06101 }
06102 }
06103 }
06104
06105 LeaveCriticalSection(&critsec);
06106
06107
return (!!
ghModSetupAPIDll);
06108 }
06109
06110
#else
06111
06112
06113
06114
06115
06116
VOID
06117 ChangeICMSetting(
06118 LPCTSTR pMachineName,
06119 LPCTSTR pDeviceName,
06120 DWORD dwICMMode
06121 )
06122 {
06123 PRINTER_INFO_8 *ppi8;
06124 PRINTER_INFO_9 *ppi9;
06125 PRINTER_DEFAULTS
pd;
06126 HANDLE hPrinter;
06127
DWORD dwSize;
06128
BYTE temp[2*1024];
06129
06130
pd.pDatatype =
NULL;
06131
pd.pDevMode =
NULL;
06132
pd.DesiredAccess = PRINTER_ALL_ACCESS;
06133
06134
if (!OpenPrinter((PTSTR)pDeviceName, &hPrinter, &
pd))
06135
return;
06136
06137
06138
06139
06140
06141 ppi8 = (PRINTER_INFO_8 *)&temp;
06142
if (GetPrinter(hPrinter, 8, (
PBYTE)ppi8,
sizeof(temp), &dwSize) &&
06143 ppi8->pDevMode)
06144 {
06145
switch (dwICMMode)
06146 {
06147
case ICM_ON:
06148
case ICM_OFF:
06149 ppi8->pDevMode->dmFields |= DM_ICMMETHOD;
06150
if (dwICMMode == ICM_ON)
06151 ppi8->pDevMode->dmICMMethod = DMICMMETHOD_SYSTEM;
06152
else
06153 ppi8->pDevMode->dmICMMethod = DMICMMETHOD_NONE;
06154 SetPrinter(hPrinter, 8, (
PBYTE)ppi8, 0);
06155
break;
06156 }
06157 }
06158
06159
06160
06161
06162
06163 ppi9 = (PRINTER_INFO_9 *)&temp;
06164
if (GetPrinter(hPrinter, 9, (
PBYTE)ppi9,
sizeof(temp), &dwSize) &&
06165 ppi9->pDevMode)
06166 {
06167
switch (dwICMMode)
06168 {
06169
case ICM_ON:
06170
case ICM_OFF:
06171 ppi9->pDevMode->dmFields |= DM_ICMMETHOD;
06172
if (dwICMMode == ICM_ON)
06173 ppi9->pDevMode->dmICMMethod = DMICMMETHOD_SYSTEM;
06174
else
06175 ppi9->pDevMode->dmICMMethod = DMICMMETHOD_NONE;
06176 SetPrinter(hPrinter, 9, (
PBYTE)ppi9, 0);
06177
break;
06178 }
06179 }
06180
06181 ClosePrinter(hPrinter);
06182
06183
return;
06184 }
06185
06186
#endif // _WIN95_
06187
06188